blob: c04bed15249269905d007f0103e94711e594e7e6 [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();
Ed Tanousc2ebddd2025-03-09 10:07:01 -0700151 json_object *type = 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).
Ed Tanousc2ebddd2025-03-09 10:07:01 -0700154 add_guid(type, "guid", &error_info->ErrorType);
Lawrence Tang794312c2022-07-05 14:46:10 +0100155
Lawrence Tang3592da72022-07-21 16:50:07 +0100156 //Get the error structure type as a readable string.
157 const char *readable_type = "Unknown";
158 if (guid_equal(&error_info->ErrorType,
John Chungf8fc7052024-05-03 20:05:29 +0800159 &gEfiIa32x64ErrorTypeCacheCheckGuid)) {
Lawrence Tang3592da72022-07-21 16:50:07 +0100160 readable_type = "Cache Check Error";
John Chungf8fc7052024-05-03 20:05:29 +0800161 } else if (guid_equal(&error_info->ErrorType,
162 &gEfiIa32x64ErrorTypeTlbCheckGuid)) {
Lawrence Tang3592da72022-07-21 16:50:07 +0100163 readable_type = "TLB Check Error";
John Chungf8fc7052024-05-03 20:05:29 +0800164 } else if (guid_equal(&error_info->ErrorType,
165 &gEfiIa32x64ErrorTypeBusCheckGuid)) {
Lawrence Tang3592da72022-07-21 16:50:07 +0100166 readable_type = "Bus Check Error";
John Chungf8fc7052024-05-03 20:05:29 +0800167 } else if (guid_equal(&error_info->ErrorType,
168 &gEfiIa32x64ErrorTypeMsCheckGuid)) {
Lawrence Tang3592da72022-07-21 16:50:07 +0100169 readable_type = "MS Check Error";
John Chungf8fc7052024-05-03 20:05:29 +0800170 }
171 json_object_object_add(type, "name",
172 json_object_new_string(readable_type));
Lawrence Tang3592da72022-07-21 16:50:07 +0100173 json_object_object_add(error_info_ir, "type", type);
174
Lawrence Tange407b4c2022-07-21 13:54:01 +0100175 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800176 ValidationTypes ui64Type = { UINT_64T,
177 .value.ui64 = error_info->ValidFields };
Lawrence Tang794312c2022-07-05 14:46:10 +0100178
Lawrence Tange407b4c2022-07-21 13:54:01 +0100179 //Add the check information on a per-structure basis.
180 //Cache and TLB check information are identical, so can be equated.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800181 if (isvalid_prop_to_ir(&ui64Type, 0)) {
182 json_object *check_information = NULL;
183 if (guid_equal(&error_info->ErrorType,
184 &gEfiIa32x64ErrorTypeCacheCheckGuid) ||
185 guid_equal(&error_info->ErrorType,
186 &gEfiIa32x64ErrorTypeTlbCheckGuid)) {
187 check_information = cper_ia32x64_cache_tlb_check_to_ir(
188 (EFI_IA32_X64_CACHE_CHECK_INFO *)&error_info
189 ->CheckInfo);
190 } else if (guid_equal(&error_info->ErrorType,
191 &gEfiIa32x64ErrorTypeBusCheckGuid)) {
192 check_information = cper_ia32x64_bus_check_to_ir(
193 (EFI_IA32_X64_BUS_CHECK_INFO *)&error_info
194 ->CheckInfo);
195 } else if (guid_equal(&error_info->ErrorType,
196 &gEfiIa32x64ErrorTypeMsCheckGuid)) {
197 check_information = cper_ia32x64_ms_check_to_ir(
198 (EFI_IA32_X64_MS_CHECK_INFO *)&error_info
199 ->CheckInfo);
200
201 } else {
202 //Unknown check information.
203 printf("WARN: Invalid/unknown check information GUID found in IA32/x64 CPER section. Ignoring.\n");
204 }
205 json_object_object_add(error_info_ir, "checkInfo",
206 check_information);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100207 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100208
Lawrence Tange407b4c2022-07-21 13:54:01 +0100209 //Target, requestor, and responder identifiers.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800210 if (isvalid_prop_to_ir(&ui64Type, 1)) {
211 json_object_object_add(
212 error_info_ir, "targetAddressID",
213 json_object_new_uint64(error_info->TargetId));
214 }
215 if (isvalid_prop_to_ir(&ui64Type, 2)) {
216 json_object_object_add(
217 error_info_ir, "requestorID",
218 json_object_new_uint64(error_info->RequestorId));
219 }
220 if (isvalid_prop_to_ir(&ui64Type, 3)) {
221 json_object_object_add(
222 error_info_ir, "responderID",
223 json_object_new_uint64(error_info->ResponderId));
224 }
225 if (isvalid_prop_to_ir(&ui64Type, 4)) {
226 json_object_object_add(
227 error_info_ir, "instructionPointer",
228 json_object_new_uint64(error_info->InstructionIP));
229 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100230
Lawrence Tange407b4c2022-07-21 13:54:01 +0100231 return error_info_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100232}
233
234//Converts a single IA32/x64 cache or TLB check check info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100235json_object *cper_ia32x64_cache_tlb_check_to_ir(
236 EFI_IA32_X64_CACHE_CHECK_INFO *cache_tlb_check)
Lawrence Tang794312c2022-07-05 14:46:10 +0100237{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100238 json_object *cache_tlb_check_ir = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +0100239
Lawrence Tange407b4c2022-07-21 13:54:01 +0100240 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800241 ValidationTypes ui64Type = {
242 UINT_64T, .value.ui64 = cache_tlb_check->ValidFields
243 };
Lawrence Tang794312c2022-07-05 14:46:10 +0100244
Lawrence Tange407b4c2022-07-21 13:54:01 +0100245 //Transaction type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800246 if (isvalid_prop_to_ir(&ui64Type, 0)) {
247 json_object *transaction_type = integer_to_readable_pair(
248 cache_tlb_check->TransactionType, 3,
249 IA32X64_CHECK_INFO_TRANSACTION_TYPES_KEYS,
250 IA32X64_CHECK_INFO_TRANSACTION_TYPES_VALUES,
251 "Unknown (Reserved)");
252 json_object_object_add(cache_tlb_check_ir, "transactionType",
253 transaction_type);
254 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100255
Lawrence Tange407b4c2022-07-21 13:54:01 +0100256 //Operation.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800257 if (isvalid_prop_to_ir(&ui64Type, 1)) {
258 json_object *operation = integer_to_readable_pair(
259 cache_tlb_check->Operation, 9,
260 IA32X64_CHECK_INFO_OPERATION_TYPES_KEYS,
261 IA32X64_CHECK_INFO_OPERATION_TYPES_VALUES,
262 "Unknown (Reserved)");
263 json_object_object_add(cache_tlb_check_ir, "operation",
264 operation);
265 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100266
Lawrence Tange407b4c2022-07-21 13:54:01 +0100267 //Affected cache/TLB level.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800268 if (isvalid_prop_to_ir(&ui64Type, 2)) {
269 json_object_object_add(
270 cache_tlb_check_ir, "level",
271 json_object_new_uint64(cache_tlb_check->Level));
272 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100273
Lawrence Tange407b4c2022-07-21 13:54:01 +0100274 //Miscellaneous boolean fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800275 if (isvalid_prop_to_ir(&ui64Type, 3)) {
276 json_object_object_add(
277 cache_tlb_check_ir, "processorContextCorrupt",
278 json_object_new_boolean(
279 cache_tlb_check->ContextCorrupt));
280 }
281 if (isvalid_prop_to_ir(&ui64Type, 4)) {
282 json_object_object_add(
283 cache_tlb_check_ir, "uncorrected",
284 json_object_new_boolean(
285 cache_tlb_check->ErrorUncorrected));
286 }
287 if (isvalid_prop_to_ir(&ui64Type, 5)) {
288 json_object_object_add(
289 cache_tlb_check_ir, "preciseIP",
290 json_object_new_boolean(cache_tlb_check->PreciseIp));
291 }
292 if (isvalid_prop_to_ir(&ui64Type, 6)) {
293 json_object_object_add(cache_tlb_check_ir, "restartableIP",
294 json_object_new_boolean(
295 cache_tlb_check->RestartableIp));
296 }
297 if (isvalid_prop_to_ir(&ui64Type, 7)) {
298 json_object_object_add(
299 cache_tlb_check_ir, "overflow",
300 json_object_new_boolean(cache_tlb_check->Overflow));
301 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100302
Lawrence Tange407b4c2022-07-21 13:54:01 +0100303 return cache_tlb_check_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100304}
305
306//Converts a single IA32/x64 bus check check info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100307json_object *
308cper_ia32x64_bus_check_to_ir(EFI_IA32_X64_BUS_CHECK_INFO *bus_check)
309{
310 json_object *bus_check_ir = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +0100311
Lawrence Tange407b4c2022-07-21 13:54:01 +0100312 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800313 ValidationTypes ui64Type = { UINT_64T,
314 .value.ui64 = bus_check->ValidFields };
Lawrence Tang794312c2022-07-05 14:46:10 +0100315
Lawrence Tange407b4c2022-07-21 13:54:01 +0100316 //Transaction type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800317 if (isvalid_prop_to_ir(&ui64Type, 0)) {
318 json_object *transaction_type = integer_to_readable_pair(
319 bus_check->TransactionType, 3,
320 IA32X64_CHECK_INFO_TRANSACTION_TYPES_KEYS,
321 IA32X64_CHECK_INFO_TRANSACTION_TYPES_VALUES,
322 "Unknown (Reserved)");
323 json_object_object_add(bus_check_ir, "transactionType",
324 transaction_type);
325 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100326
Lawrence Tange407b4c2022-07-21 13:54:01 +0100327 //Operation.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800328 if (isvalid_prop_to_ir(&ui64Type, 1)) {
329 json_object *operation = integer_to_readable_pair(
330 bus_check->Operation, 9,
331 IA32X64_CHECK_INFO_OPERATION_TYPES_KEYS,
332 IA32X64_CHECK_INFO_OPERATION_TYPES_VALUES,
333 "Unknown (Reserved)");
334 json_object_object_add(bus_check_ir, "operation", operation);
335 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100336
Lawrence Tange407b4c2022-07-21 13:54:01 +0100337 //Affected bus level.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800338 if (isvalid_prop_to_ir(&ui64Type, 2)) {
339 json_object_object_add(
340 bus_check_ir, "level",
341 json_object_new_uint64(bus_check->Level));
342 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100343
Lawrence Tange407b4c2022-07-21 13:54:01 +0100344 //Miscellaneous boolean fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800345 if (isvalid_prop_to_ir(&ui64Type, 3)) {
346 json_object_object_add(
347 bus_check_ir, "processorContextCorrupt",
348 json_object_new_boolean(bus_check->ContextCorrupt));
349 }
350 if (isvalid_prop_to_ir(&ui64Type, 4)) {
351 json_object_object_add(
352 bus_check_ir, "uncorrected",
353 json_object_new_boolean(bus_check->ErrorUncorrected));
354 }
355 if (isvalid_prop_to_ir(&ui64Type, 5)) {
356 json_object_object_add(
357 bus_check_ir, "preciseIP",
358 json_object_new_boolean(bus_check->PreciseIp));
359 }
360 if (isvalid_prop_to_ir(&ui64Type, 6)) {
361 json_object_object_add(
362 bus_check_ir, "restartableIP",
363 json_object_new_boolean(bus_check->RestartableIp));
364 }
365 if (isvalid_prop_to_ir(&ui64Type, 7)) {
366 json_object_object_add(
367 bus_check_ir, "overflow",
368 json_object_new_boolean(bus_check->Overflow));
369 }
370 if (isvalid_prop_to_ir(&ui64Type, 9)) {
371 json_object_object_add(
372 bus_check_ir, "timedOut",
373 json_object_new_boolean(bus_check->TimeOut));
374 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100375
Lawrence Tange407b4c2022-07-21 13:54:01 +0100376 //Participation type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800377 if (isvalid_prop_to_ir(&ui64Type, 8)) {
378 json_object *participation_type = integer_to_readable_pair(
379 bus_check->ParticipationType, 4,
380 IA32X64_BUS_CHECK_INFO_PARTICIPATION_TYPES_KEYS,
381 IA32X64_BUS_CHECK_INFO_PARTICIPATION_TYPES_VALUES,
382 "Unknown");
383 json_object_object_add(bus_check_ir, "participationType",
384 participation_type);
385 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100386
Lawrence Tange407b4c2022-07-21 13:54:01 +0100387 //Address space.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800388 if (isvalid_prop_to_ir(&ui64Type, 10)) {
389 json_object *address_space = integer_to_readable_pair(
390 bus_check->AddressSpace, 4,
391 IA32X64_BUS_CHECK_INFO_ADDRESS_SPACE_TYPES_KEYS,
392 IA32X64_BUS_CHECK_INFO_ADDRESS_SPACE_TYPES_VALUES,
393 "Unknown");
394 json_object_object_add(bus_check_ir, "addressSpace",
395 address_space);
396 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100397
398 return bus_check_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100399}
400
401//Converts a single IA32/x64 MS check check info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100402json_object *cper_ia32x64_ms_check_to_ir(EFI_IA32_X64_MS_CHECK_INFO *ms_check)
Lawrence Tang794312c2022-07-05 14:46:10 +0100403{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100404 json_object *ms_check_ir = json_object_new_object();
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800405 ValidationTypes ui64Type = { UINT_64T,
406 .value.ui64 = ms_check->ValidFields };
Lawrence Tange407b4c2022-07-21 13:54:01 +0100407 //Validation bits.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100408 //Error type (operation that caused the error).
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800409 if (isvalid_prop_to_ir(&ui64Type, 0)) {
410 json_object *error_type = integer_to_readable_pair(
411 ms_check->ErrorType, 4,
412 IA32X64_MS_CHECK_INFO_ERROR_TYPES_KEYS,
413 IA32X64_MS_CHECK_INFO_ERROR_TYPES_VALUES,
414 "Unknown (Processor Specific)");
415 json_object_object_add(ms_check_ir, "errorType", error_type);
416 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100417
Lawrence Tange407b4c2022-07-21 13:54:01 +0100418 //Miscellaneous fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800419 if (isvalid_prop_to_ir(&ui64Type, 1)) {
420 json_object_object_add(
421 ms_check_ir, "processorContextCorrupt",
422 json_object_new_boolean(ms_check->ContextCorrupt));
423 }
424 if (isvalid_prop_to_ir(&ui64Type, 2)) {
425 json_object_object_add(
426 ms_check_ir, "uncorrected",
427 json_object_new_boolean(ms_check->ErrorUncorrected));
428 }
429 if (isvalid_prop_to_ir(&ui64Type, 3)) {
430 json_object_object_add(
431 ms_check_ir, "preciseIP",
432 json_object_new_boolean(ms_check->PreciseIp));
433 }
434 if (isvalid_prop_to_ir(&ui64Type, 4)) {
435 json_object_object_add(
436 ms_check_ir, "restartableIP",
437 json_object_new_boolean(ms_check->RestartableIp));
438 }
439 if (isvalid_prop_to_ir(&ui64Type, 5)) {
440 json_object_object_add(
441 ms_check_ir, "overflow",
442 json_object_new_boolean(ms_check->Overflow));
443 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100444
445 return ms_check_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100446}
447
448//Converts a single IA32/x64 processor context info entry into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100449json_object *cper_ia32x64_processor_context_info_to_ir(
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800450 EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *context_info, void **cur_pos,
451 UINT32 *remaining_size)
Lawrence Tang794312c2022-07-05 14:46:10 +0100452{
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800453 if (*remaining_size < sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO)) {
454 return NULL;
455 }
456 *remaining_size -= sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100457 json_object *context_info_ir = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +0100458
Lawrence Tange407b4c2022-07-21 13:54:01 +0100459 //Register context type.
460 json_object *context_type = integer_to_readable_pair(
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800461 context_info->RegisterType, IA32X64_REGISTER_CONTEXT_TYPES_SIZE,
Lawrence Tange407b4c2022-07-21 13:54:01 +0100462 IA32X64_REGISTER_CONTEXT_TYPES_KEYS,
463 IA32X64_REGISTER_CONTEXT_TYPES_VALUES, "Unknown (Reserved)");
464 json_object_object_add(context_info_ir, "registerContextType",
465 context_type);
Lawrence Tang794312c2022-07-05 14:46:10 +0100466
Lawrence Tange407b4c2022-07-21 13:54:01 +0100467 //Register array size, MSR and MM address.
468 json_object_object_add(context_info_ir, "registerArraySize",
469 json_object_new_uint64(context_info->ArraySize));
470 json_object_object_add(
471 context_info_ir, "msrAddress",
472 json_object_new_uint64(context_info->MsrAddress));
473 json_object_object_add(
474 context_info_ir, "mmRegisterAddress",
475 json_object_new_uint64(context_info->MmRegisterAddress));
Lawrence Tang794312c2022-07-05 14:46:10 +0100476
Lawrence Tange407b4c2022-07-21 13:54:01 +0100477 //Register array.
478 json_object *register_array = NULL;
479 if (context_info->RegisterType == EFI_REG_CONTEXT_TYPE_IA32) {
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800480 if (*remaining_size < sizeof(EFI_CONTEXT_IA32_REGISTER_STATE)) {
481 json_object_put(context_info_ir);
482 return NULL;
483 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100484 EFI_CONTEXT_IA32_REGISTER_STATE *register_state =
485 (EFI_CONTEXT_IA32_REGISTER_STATE *)(context_info + 1);
486 register_array =
487 cper_ia32x64_register_32bit_to_ir(register_state);
488 *cur_pos = (void *)(register_state + 1);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800489 *remaining_size -= sizeof(EFI_CONTEXT_IA32_REGISTER_STATE);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100490 } else if (context_info->RegisterType == EFI_REG_CONTEXT_TYPE_X64) {
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800491 if (*remaining_size < sizeof(EFI_CONTEXT_X64_REGISTER_STATE)) {
492 json_object_put(context_info_ir);
493 return NULL;
494 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100495 EFI_CONTEXT_X64_REGISTER_STATE *register_state =
496 (EFI_CONTEXT_X64_REGISTER_STATE *)(context_info + 1);
497 register_array =
498 cper_ia32x64_register_64bit_to_ir(register_state);
499 *cur_pos = (void *)(register_state + 1);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800500 *remaining_size -= sizeof(EFI_CONTEXT_X64_REGISTER_STATE);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100501 } else {
502 //No parseable data, just dump as base64 and shift the head to the next item.
503 *cur_pos = (void *)(context_info + 1);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800504 if (*remaining_size < context_info->ArraySize) {
505 json_object_put(context_info_ir);
506 return NULL;
507 }
Ed Tanousa7d2cdd2024-07-15 11:07:27 -0700508 int32_t encoded_len = 0;
509 char *encoded = base64_encode((UINT8 *)*cur_pos,
510 context_info->ArraySize,
511 &encoded_len);
512 if (encoded == NULL) {
John Chungf8fc7052024-05-03 20:05:29 +0800513 printf("Failed to allocate encode output buffer. \n");
514 } else {
John Chungf8fc7052024-05-03 20:05:29 +0800515 register_array = json_object_new_object();
516 json_object_object_add(register_array, "data",
517 json_object_new_string_len(
518 encoded, encoded_len));
519 free(encoded);
520 }
Lawrence Tangd7e8ca32022-07-07 10:25:53 +0100521
Lawrence Tange407b4c2022-07-21 13:54:01 +0100522 *cur_pos =
523 (void *)(((char *)*cur_pos) + context_info->ArraySize);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800524 *remaining_size -= context_info->ArraySize;
Lawrence Tange407b4c2022-07-21 13:54:01 +0100525 }
526 json_object_object_add(context_info_ir, "registerArray",
527 register_array);
Lawrence Tang794312c2022-07-05 14:46:10 +0100528
Lawrence Tange407b4c2022-07-21 13:54:01 +0100529 return context_info_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100530}
531
532//Converts a single CPER IA32 register state into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100533json_object *
534cper_ia32x64_register_32bit_to_ir(EFI_CONTEXT_IA32_REGISTER_STATE *registers)
Lawrence Tang794312c2022-07-05 14:46:10 +0100535{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100536 json_object *ia32_registers = json_object_new_object();
537 json_object_object_add(ia32_registers, "eax",
538 json_object_new_uint64(registers->Eax));
539 json_object_object_add(ia32_registers, "ebx",
540 json_object_new_uint64(registers->Ebx));
541 json_object_object_add(ia32_registers, "ecx",
542 json_object_new_uint64(registers->Ecx));
543 json_object_object_add(ia32_registers, "edx",
544 json_object_new_uint64(registers->Edx));
545 json_object_object_add(ia32_registers, "esi",
546 json_object_new_uint64(registers->Esi));
547 json_object_object_add(ia32_registers, "edi",
548 json_object_new_uint64(registers->Edi));
549 json_object_object_add(ia32_registers, "ebp",
550 json_object_new_uint64(registers->Ebp));
551 json_object_object_add(ia32_registers, "esp",
552 json_object_new_uint64(registers->Esp));
553 json_object_object_add(ia32_registers, "cs",
554 json_object_new_uint64(registers->Cs));
555 json_object_object_add(ia32_registers, "ds",
556 json_object_new_uint64(registers->Ds));
557 json_object_object_add(ia32_registers, "ss",
558 json_object_new_uint64(registers->Ss));
559 json_object_object_add(ia32_registers, "es",
560 json_object_new_uint64(registers->Es));
561 json_object_object_add(ia32_registers, "fs",
562 json_object_new_uint64(registers->Fs));
563 json_object_object_add(ia32_registers, "gs",
564 json_object_new_uint64(registers->Gs));
565 json_object_object_add(ia32_registers, "eflags",
566 json_object_new_uint64(registers->Eflags));
567 json_object_object_add(ia32_registers, "eip",
568 json_object_new_uint64(registers->Eip));
569 json_object_object_add(ia32_registers, "cr0",
570 json_object_new_uint64(registers->Cr0));
571 json_object_object_add(ia32_registers, "cr1",
572 json_object_new_uint64(registers->Cr1));
573 json_object_object_add(ia32_registers, "cr2",
574 json_object_new_uint64(registers->Cr2));
575 json_object_object_add(ia32_registers, "cr3",
576 json_object_new_uint64(registers->Cr3));
577 json_object_object_add(ia32_registers, "cr4",
578 json_object_new_uint64(registers->Cr4));
579 json_object_object_add(
580 ia32_registers, "gdtr",
581 json_object_new_uint64(registers->Gdtr[0] +
582 ((UINT64)registers->Gdtr[1] << 32)));
583 json_object_object_add(
584 ia32_registers, "idtr",
585 json_object_new_uint64(registers->Idtr[0] +
586 ((UINT64)registers->Idtr[1] << 32)));
587 json_object_object_add(ia32_registers, "ldtr",
588 json_object_new_uint64(registers->Ldtr));
589 json_object_object_add(ia32_registers, "tr",
590 json_object_new_uint64(registers->Tr));
Lawrence Tang794312c2022-07-05 14:46:10 +0100591
Lawrence Tange407b4c2022-07-21 13:54:01 +0100592 return ia32_registers;
Lawrence Tang794312c2022-07-05 14:46:10 +0100593}
594
595//Converts a single CPER x64 register state into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100596json_object *
597cper_ia32x64_register_64bit_to_ir(EFI_CONTEXT_X64_REGISTER_STATE *registers)
Lawrence Tang794312c2022-07-05 14:46:10 +0100598{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100599 json_object *x64_registers = json_object_new_object();
600 json_object_object_add(x64_registers, "rax",
601 json_object_new_uint64(registers->Rax));
602 json_object_object_add(x64_registers, "rbx",
603 json_object_new_uint64(registers->Rbx));
604 json_object_object_add(x64_registers, "rcx",
605 json_object_new_uint64(registers->Rcx));
606 json_object_object_add(x64_registers, "rdx",
607 json_object_new_uint64(registers->Rdx));
608 json_object_object_add(x64_registers, "rsi",
609 json_object_new_uint64(registers->Rsi));
610 json_object_object_add(x64_registers, "rdi",
611 json_object_new_uint64(registers->Rdi));
612 json_object_object_add(x64_registers, "rbp",
613 json_object_new_uint64(registers->Rbp));
614 json_object_object_add(x64_registers, "rsp",
615 json_object_new_uint64(registers->Rsp));
616 json_object_object_add(x64_registers, "r8",
617 json_object_new_uint64(registers->R8));
618 json_object_object_add(x64_registers, "r9",
619 json_object_new_uint64(registers->R9));
620 json_object_object_add(x64_registers, "r10",
621 json_object_new_uint64(registers->R10));
622 json_object_object_add(x64_registers, "r11",
623 json_object_new_uint64(registers->R11));
624 json_object_object_add(x64_registers, "r12",
625 json_object_new_uint64(registers->R12));
626 json_object_object_add(x64_registers, "r13",
627 json_object_new_uint64(registers->R13));
628 json_object_object_add(x64_registers, "r14",
629 json_object_new_uint64(registers->R14));
630 json_object_object_add(x64_registers, "r15",
631 json_object_new_uint64(registers->R15));
632 json_object_object_add(x64_registers, "cs",
633 json_object_new_int(registers->Cs));
634 json_object_object_add(x64_registers, "ds",
635 json_object_new_int(registers->Ds));
636 json_object_object_add(x64_registers, "ss",
637 json_object_new_int(registers->Ss));
638 json_object_object_add(x64_registers, "es",
639 json_object_new_int(registers->Es));
640 json_object_object_add(x64_registers, "fs",
641 json_object_new_int(registers->Fs));
642 json_object_object_add(x64_registers, "gs",
643 json_object_new_int(registers->Gs));
644 json_object_object_add(x64_registers, "rflags",
645 json_object_new_uint64(registers->Rflags));
646 json_object_object_add(x64_registers, "eip",
647 json_object_new_uint64(registers->Rip));
648 json_object_object_add(x64_registers, "cr0",
649 json_object_new_uint64(registers->Cr0));
650 json_object_object_add(x64_registers, "cr1",
651 json_object_new_uint64(registers->Cr1));
652 json_object_object_add(x64_registers, "cr2",
653 json_object_new_uint64(registers->Cr2));
654 json_object_object_add(x64_registers, "cr3",
655 json_object_new_uint64(registers->Cr3));
656 json_object_object_add(x64_registers, "cr4",
657 json_object_new_uint64(registers->Cr4));
658 json_object_object_add(x64_registers, "cr8",
659 json_object_new_uint64(registers->Cr8));
660 json_object_object_add(x64_registers, "gdtr_0",
661 json_object_new_uint64(registers->Gdtr[0]));
662 json_object_object_add(x64_registers, "gdtr_1",
663 json_object_new_uint64(registers->Gdtr[1]));
664 json_object_object_add(x64_registers, "idtr_0",
665 json_object_new_uint64(registers->Idtr[0]));
666 json_object_object_add(x64_registers, "idtr_1",
667 json_object_new_uint64(registers->Idtr[1]));
668 json_object_object_add(x64_registers, "ldtr",
669 json_object_new_int(registers->Ldtr));
670 json_object_object_add(x64_registers, "tr",
671 json_object_new_int(registers->Tr));
Lawrence Tang794312c2022-07-05 14:46:10 +0100672
Lawrence Tange407b4c2022-07-21 13:54:01 +0100673 return x64_registers;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100674}
675
676//////////////////
677/// IR TO CPER ///
678//////////////////
679
680//Converts a single IA32/x64 CPER-JSON section into CPER binary, outputting to the provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100681void ir_section_ia32x64_to_cper(json_object *section, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100682{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100683 EFI_IA32_X64_PROCESSOR_ERROR_RECORD *section_cper =
684 (EFI_IA32_X64_PROCESSOR_ERROR_RECORD *)calloc(
685 1, sizeof(EFI_IA32_X64_PROCESSOR_ERROR_RECORD));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100686
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800687 uint64_t valid = 0x0;
688
689 int proc_error_info_num = json_object_get_int(json_object_object_get(
690 section, "processorErrorInfoNum")) &
691 0x3F;
692 int proc_ctx_info_num = json_object_get_int(json_object_object_get(
693 section, "processorContextInfoNum")) &
694 0x3F;
695 valid |= proc_error_info_num << 2;
696 valid |= proc_ctx_info_num << 8;
697
698 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = valid };
699 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100700
Lawrence Tange407b4c2022-07-21 13:54:01 +0100701 //Local APIC ID.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800702 if (json_object_object_get_ex(section, "localAPICID", &obj)) {
703 section_cper->ApicId = json_object_get_uint64(obj);
704 add_to_valid_bitfield(&ui64Type, 0);
705 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100706
Lawrence Tange407b4c2022-07-21 13:54:01 +0100707 //CPUID info.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800708 if (json_object_object_get_ex(section, "cpuidInfo", &obj)) {
709 json_object *cpuid_info = obj;
710 EFI_IA32_X64_CPU_ID *cpuid_info_cper =
711 (EFI_IA32_X64_CPU_ID *)section_cper->CpuIdInfo;
712 cpuid_info_cper->Eax = json_object_get_uint64(
713 json_object_object_get(cpuid_info, "eax"));
714 cpuid_info_cper->Ebx = json_object_get_uint64(
715 json_object_object_get(cpuid_info, "ebx"));
716 cpuid_info_cper->Ecx = json_object_get_uint64(
717 json_object_object_get(cpuid_info, "ecx"));
718 cpuid_info_cper->Edx = json_object_get_uint64(
719 json_object_object_get(cpuid_info, "edx"));
720 add_to_valid_bitfield(&ui64Type, 1);
721 }
722 section_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100723
Lawrence Tange407b4c2022-07-21 13:54:01 +0100724 //Flush the header to file before dealing w/ info sections.
725 fwrite(section_cper, sizeof(EFI_IA32_X64_PROCESSOR_ERROR_RECORD), 1,
726 out);
727 fflush(out);
728 free(section_cper);
729
730 //Iterate and deal with sections.
731 json_object *error_info =
732 json_object_object_get(section, "processorErrorInfo");
733 json_object *context_info =
734 json_object_object_get(section, "processorContextInfo");
John Chungf8fc7052024-05-03 20:05:29 +0800735 for (int i = 0; i < proc_error_info_num; i++) {
Lawrence Tange407b4c2022-07-21 13:54:01 +0100736 ir_ia32x64_error_info_to_cper(
737 json_object_array_get_idx(error_info, i), out);
John Chungf8fc7052024-05-03 20:05:29 +0800738 }
739 for (int i = 0; i < proc_ctx_info_num; i++) {
Lawrence Tange407b4c2022-07-21 13:54:01 +0100740 ir_ia32x64_context_info_to_cper(
741 json_object_array_get_idx(context_info, i), out);
John Chungf8fc7052024-05-03 20:05:29 +0800742 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100743}
744
745//Converts a single CPER-JSON IA32/x64 error information structure into CPER binary, outputting to the
746//provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100747void ir_ia32x64_error_info_to_cper(json_object *error_info, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100748{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100749 EFI_IA32_X64_PROCESS_ERROR_INFO *error_info_cper =
750 (EFI_IA32_X64_PROCESS_ERROR_INFO *)calloc(
751 1, sizeof(EFI_IA32_X64_PROCESS_ERROR_INFO));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100752
Lawrence Tange407b4c2022-07-21 13:54:01 +0100753 //Error structure type.
Lawrence Tang3592da72022-07-21 16:50:07 +0100754 json_object *type = json_object_object_get(error_info, "type");
755 string_to_guid(
756 &error_info_cper->ErrorType,
757 json_object_get_string(json_object_object_get(type, "guid")));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100758
Lawrence Tange407b4c2022-07-21 13:54:01 +0100759 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800760 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
761 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100762
Lawrence Tange407b4c2022-07-21 13:54:01 +0100763 //Check information, parsed based on the error type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800764 if (json_object_object_get_ex(error_info, "checkInfo", &obj)) {
765 json_object *check_info = obj;
766 if (guid_equal(&error_info_cper->ErrorType,
767 &gEfiIa32x64ErrorTypeCacheCheckGuid) ||
768 guid_equal(&error_info_cper->ErrorType,
769 &gEfiIa32x64ErrorTypeTlbCheckGuid)) {
770 ir_ia32x64_cache_tlb_check_error_to_cper(
771 check_info,
772 (EFI_IA32_X64_CACHE_CHECK_INFO
773 *)&error_info_cper->CheckInfo);
774 } else if (guid_equal(&error_info_cper->ErrorType,
775 &gEfiIa32x64ErrorTypeBusCheckGuid)) {
776 ir_ia32x64_bus_check_error_to_cper(
777 check_info,
778 (EFI_IA32_X64_BUS_CHECK_INFO *)&error_info_cper
779 ->CheckInfo);
780 } else if (guid_equal(&error_info_cper->ErrorType,
781 &gEfiIa32x64ErrorTypeMsCheckGuid)) {
782 ir_ia32x64_ms_check_error_to_cper(
783 check_info,
784 (EFI_IA32_X64_MS_CHECK_INFO *)&error_info_cper
785 ->CheckInfo);
786 }
787 add_to_valid_bitfield(&ui64Type, 0);
John Chungf8fc7052024-05-03 20:05:29 +0800788 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100789
Lawrence Tange407b4c2022-07-21 13:54:01 +0100790 //Miscellaneous numeric fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800791 if (json_object_object_get_ex(error_info, "targetAddressID", &obj)) {
792 error_info_cper->TargetId = json_object_get_uint64(obj);
793 add_to_valid_bitfield(&ui64Type, 1);
794 }
795 if (json_object_object_get_ex(error_info, "requestorID", &obj)) {
796 error_info_cper->RequestorId = json_object_get_uint64(obj);
797 add_to_valid_bitfield(&ui64Type, 2);
798 }
799 if (json_object_object_get_ex(error_info, "responderID", &obj)) {
800 error_info_cper->ResponderId = json_object_get_uint64(obj);
801 add_to_valid_bitfield(&ui64Type, 3);
802 }
803 if (json_object_object_get_ex(error_info, "instructionPointer", &obj)) {
804 error_info_cper->InstructionIP = json_object_get_uint64(obj);
805 add_to_valid_bitfield(&ui64Type, 4);
806 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100807
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800808 error_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tange407b4c2022-07-21 13:54:01 +0100809 //Write out to stream, then free resources.
810 fwrite(error_info_cper, sizeof(EFI_IA32_X64_PROCESS_ERROR_INFO), 1,
811 out);
812 fflush(out);
813 free(error_info_cper);
Lawrence Tangd0c88842022-07-13 14:51:17 +0100814}
815
816//Converts a single CPER-JSON IA32/x64 cache/TLB check error info structure to CPER binary.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100817void ir_ia32x64_cache_tlb_check_error_to_cper(
818 json_object *check_info, EFI_IA32_X64_CACHE_CHECK_INFO *check_info_cper)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100819{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100820 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800821 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
822 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100823
Lawrence Tange407b4c2022-07-21 13:54:01 +0100824 //Transaction type, operation.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800825 if (json_object_object_get_ex(check_info, "transactionType", &obj)) {
826 check_info_cper->TransactionType =
827 readable_pair_to_integer(obj);
828 add_to_valid_bitfield(&ui64Type, 0);
829 }
830 if (json_object_object_get_ex(check_info, "operation", &obj)) {
831 check_info_cper->Operation = readable_pair_to_integer(obj);
832 add_to_valid_bitfield(&ui64Type, 1);
833 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100834
Lawrence Tange407b4c2022-07-21 13:54:01 +0100835 //Miscellaneous raw value fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800836 if (json_object_object_get_ex(check_info, "level", &obj)) {
837 check_info_cper->Level = json_object_get_uint64(obj);
838 add_to_valid_bitfield(&ui64Type, 2);
839 }
840 if (json_object_object_get_ex(check_info, "processorContextCorrupt",
841 &obj)) {
842 check_info_cper->ContextCorrupt = json_object_get_boolean(obj);
843 add_to_valid_bitfield(&ui64Type, 3);
844 }
845 if (json_object_object_get_ex(check_info, "uncorrected", &obj)) {
846 check_info_cper->ErrorUncorrected =
847 json_object_get_boolean(obj);
848 add_to_valid_bitfield(&ui64Type, 4);
849 }
850 if (json_object_object_get_ex(check_info, "preciseIP", &obj)) {
851 check_info_cper->PreciseIp = json_object_get_boolean(obj);
852 add_to_valid_bitfield(&ui64Type, 5);
853 }
854 if (json_object_object_get_ex(check_info, "restartableIP", &obj)) {
855 check_info_cper->RestartableIp = json_object_get_boolean(obj);
856 add_to_valid_bitfield(&ui64Type, 6);
857 }
858 if (json_object_object_get_ex(check_info, "overflow", &obj)) {
859 check_info_cper->Overflow = json_object_get_boolean(obj);
860 add_to_valid_bitfield(&ui64Type, 7);
861 }
862 check_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100863}
864
865//Converts a single CPER-JSON IA32/x64 bus error info structure to CPER binary.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100866void ir_ia32x64_bus_check_error_to_cper(
867 json_object *check_info, EFI_IA32_X64_BUS_CHECK_INFO *check_info_cper)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100868{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100869 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800870 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
871 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100872
Lawrence Tange407b4c2022-07-21 13:54:01 +0100873 //Readable pair fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800874 if (json_object_object_get_ex(check_info, "transactionType", &obj)) {
875 check_info_cper->TransactionType =
876 readable_pair_to_integer(obj);
877 add_to_valid_bitfield(&ui64Type, 0);
878 }
879 if (json_object_object_get_ex(check_info, "operation", &obj)) {
880 check_info_cper->Operation = readable_pair_to_integer(obj);
881 add_to_valid_bitfield(&ui64Type, 1);
882 }
883 if (json_object_object_get_ex(check_info, "participationType", &obj)) {
884 check_info_cper->ParticipationType =
885 readable_pair_to_integer(obj);
886 add_to_valid_bitfield(&ui64Type, 8);
887 }
888
889 if (json_object_object_get_ex(check_info, "addressSpace", &obj)) {
890 check_info_cper->AddressSpace = readable_pair_to_integer(obj);
891 add_to_valid_bitfield(&ui64Type, 10);
892 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100893
Lawrence Tange407b4c2022-07-21 13:54:01 +0100894 //Miscellaneous raw value fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800895 if (json_object_object_get_ex(check_info, "level", &obj)) {
896 check_info_cper->Level = json_object_get_uint64(obj);
897 add_to_valid_bitfield(&ui64Type, 2);
898 }
899 if (json_object_object_get_ex(check_info, "processorContextCorrupt",
900 &obj)) {
901 check_info_cper->ContextCorrupt = json_object_get_boolean(obj);
902 add_to_valid_bitfield(&ui64Type, 3);
903 }
904 if (json_object_object_get_ex(check_info, "uncorrected", &obj)) {
905 check_info_cper->ErrorUncorrected =
906 json_object_get_boolean(obj);
907 add_to_valid_bitfield(&ui64Type, 4);
908 }
909 if (json_object_object_get_ex(check_info, "preciseIP", &obj)) {
910 check_info_cper->PreciseIp = json_object_get_boolean(obj);
911 add_to_valid_bitfield(&ui64Type, 5);
912 }
913 if (json_object_object_get_ex(check_info, "restartableIP", &obj)) {
914 check_info_cper->RestartableIp = json_object_get_boolean(obj);
915 add_to_valid_bitfield(&ui64Type, 6);
916 }
917 if (json_object_object_get_ex(check_info, "overflow", &obj)) {
918 check_info_cper->Overflow = json_object_get_boolean(obj);
919 add_to_valid_bitfield(&ui64Type, 7);
920 }
921 if (json_object_object_get_ex(check_info, "timedOut", &obj)) {
922 check_info_cper->TimeOut = json_object_get_boolean(obj);
923 add_to_valid_bitfield(&ui64Type, 9);
924 }
925 check_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100926}
927
928//Converts a single CPER-JSON IA32/x64 MS error info structure to CPER binary.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100929void ir_ia32x64_ms_check_error_to_cper(
930 json_object *check_info, EFI_IA32_X64_MS_CHECK_INFO *check_info_cper)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100931{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100932 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800933 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
934 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100935
Lawrence Tange407b4c2022-07-21 13:54:01 +0100936 //Type of MS check error.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800937 if (json_object_object_get_ex(check_info, "errorType", &obj)) {
938 check_info_cper->ErrorType = readable_pair_to_integer(obj);
939 add_to_valid_bitfield(&ui64Type, 0);
940 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100941
Lawrence Tange407b4c2022-07-21 13:54:01 +0100942 //Miscellaneous raw value fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800943 if (json_object_object_get_ex(check_info, "processorContextCorrupt",
944 &obj)) {
945 check_info_cper->ContextCorrupt = json_object_get_boolean(obj);
946 add_to_valid_bitfield(&ui64Type, 1);
947 }
948 if (json_object_object_get_ex(check_info, "uncorrected", &obj)) {
949 check_info_cper->ErrorUncorrected =
950 json_object_get_boolean(obj);
951 add_to_valid_bitfield(&ui64Type, 2);
952 }
953 if (json_object_object_get_ex(check_info, "preciseIP", &obj)) {
954 check_info_cper->PreciseIp = json_object_get_boolean(obj);
955 add_to_valid_bitfield(&ui64Type, 3);
956 }
957 if (json_object_object_get_ex(check_info, "restartableIP", &obj)) {
958 check_info_cper->RestartableIp = json_object_get_boolean(obj);
959 add_to_valid_bitfield(&ui64Type, 4);
960 }
961 if (json_object_object_get_ex(check_info, "overflow", &obj)) {
962 check_info_cper->Overflow = json_object_get_boolean(obj);
963 add_to_valid_bitfield(&ui64Type, 5);
964 }
965 check_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100966}
967
968//Converts a single CPER-JSON IA32/x64 context information structure into CPER binary, outputting to the
969//provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100970void ir_ia32x64_context_info_to_cper(json_object *context_info, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100971{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100972 EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *context_info_cper =
973 (EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *)calloc(
974 1, sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100975
Lawrence Tange407b4c2022-07-21 13:54:01 +0100976 //Register context type.
977 context_info_cper->RegisterType = (UINT16)readable_pair_to_integer(
978 json_object_object_get(context_info, "registerContextType"));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100979
Lawrence Tange407b4c2022-07-21 13:54:01 +0100980 //Miscellaneous numeric fields.
981 context_info_cper->ArraySize = (UINT16)json_object_get_uint64(
982 json_object_object_get(context_info, "registerArraySize"));
983 context_info_cper->MsrAddress = (UINT32)json_object_get_uint64(
984 json_object_object_get(context_info, "msrAddress"));
985 context_info_cper->MmRegisterAddress = json_object_get_uint64(
986 json_object_object_get(context_info, "mmRegisterAddress"));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100987
Lawrence Tange407b4c2022-07-21 13:54:01 +0100988 //Flush header to stream.
989 fwrite(context_info_cper, sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO),
990 1, out);
991 fflush(out);
Lawrence Tangd0c88842022-07-13 14:51:17 +0100992
Lawrence Tange407b4c2022-07-21 13:54:01 +0100993 //Handle the register array, depending on type provided.
994 json_object *register_array =
995 json_object_object_get(context_info, "registerArray");
996 if (context_info_cper->RegisterType == EFI_REG_CONTEXT_TYPE_IA32) {
997 ir_ia32x64_ia32_registers_to_cper(register_array, out);
998 } else if (context_info_cper->RegisterType ==
999 EFI_REG_CONTEXT_TYPE_X64) {
1000 ir_ia32x64_x64_registers_to_cper(register_array, out);
1001 } else {
1002 //Unknown/structure is not defined.
1003 json_object *encoded =
1004 json_object_object_get(register_array, "data");
Ed Tanousa7d2cdd2024-07-15 11:07:27 -07001005 int32_t decoded_len = 0;
1006 const char *j_string = json_object_get_string(encoded);
1007 int j_size = json_object_get_string_len(encoded);
1008 UINT8 *decoded = base64_decode(j_string, j_size, &decoded_len);
1009 if (decoded == NULL) {
John Chungf8fc7052024-05-03 20:05:29 +08001010 printf("Failed to allocate decode output buffer. \n");
1011 } else {
John Chungf8fc7052024-05-03 20:05:29 +08001012 fwrite(decoded, decoded_len, 1, out);
1013 fflush(out);
1014 free(decoded);
1015 }
Lawrence Tange407b4c2022-07-21 13:54:01 +01001016 }
Lawrence Tangd0c88842022-07-13 14:51:17 +01001017
Lawrence Tange407b4c2022-07-21 13:54:01 +01001018 //Free remaining resources.
1019 free(context_info_cper);
Lawrence Tangd0c88842022-07-13 14:51:17 +01001020}
1021
1022//Converts a single CPER-JSON IA32 register array into CPER binary, outputting to the given stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +01001023void ir_ia32x64_ia32_registers_to_cper(json_object *registers, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +01001024{
Lawrence Tange407b4c2022-07-21 13:54:01 +01001025 EFI_CONTEXT_IA32_REGISTER_STATE register_state;
1026 register_state.Eax = (UINT32)json_object_get_uint64(
1027 json_object_object_get(registers, "eax"));
1028 register_state.Ebx = (UINT32)json_object_get_uint64(
1029 json_object_object_get(registers, "ebx"));
1030 register_state.Ecx = (UINT32)json_object_get_uint64(
1031 json_object_object_get(registers, "ecx"));
1032 register_state.Edx = (UINT32)json_object_get_uint64(
1033 json_object_object_get(registers, "edx"));
1034 register_state.Esi = (UINT32)json_object_get_uint64(
1035 json_object_object_get(registers, "esi"));
1036 register_state.Edi = (UINT32)json_object_get_uint64(
1037 json_object_object_get(registers, "edi"));
1038 register_state.Ebp = (UINT32)json_object_get_uint64(
1039 json_object_object_get(registers, "ebp"));
1040 register_state.Esp = (UINT32)json_object_get_uint64(
1041 json_object_object_get(registers, "esp"));
1042 register_state.Cs = (UINT16)json_object_get_uint64(
1043 json_object_object_get(registers, "cs"));
1044 register_state.Ds = (UINT32)json_object_get_uint64(
1045 json_object_object_get(registers, "ds"));
1046 register_state.Ss = (UINT16)json_object_get_uint64(
1047 json_object_object_get(registers, "ss"));
1048 register_state.Es = (UINT16)json_object_get_uint64(
1049 json_object_object_get(registers, "es"));
1050 register_state.Fs = (UINT16)json_object_get_uint64(
1051 json_object_object_get(registers, "fs"));
1052 register_state.Gs = (UINT16)json_object_get_uint64(
1053 json_object_object_get(registers, "gs"));
1054 register_state.Eflags = (UINT32)json_object_get_uint64(
1055 json_object_object_get(registers, "eflags"));
1056 register_state.Eip = (UINT32)json_object_get_uint64(
1057 json_object_object_get(registers, "eip"));
1058 register_state.Cr0 = (UINT32)json_object_get_uint64(
1059 json_object_object_get(registers, "cr0"));
1060 register_state.Cr1 = (UINT32)json_object_get_uint64(
1061 json_object_object_get(registers, "cr1"));
1062 register_state.Cr2 = (UINT32)json_object_get_uint64(
1063 json_object_object_get(registers, "cr2"));
1064 register_state.Cr3 = (UINT32)json_object_get_uint64(
1065 json_object_object_get(registers, "cr3"));
1066 register_state.Cr4 = (UINT32)json_object_get_uint64(
1067 json_object_object_get(registers, "cr4"));
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001068
Lawrence Tange407b4c2022-07-21 13:54:01 +01001069 //64-bit registers are split into two 32-bit parts.
1070 UINT64 gdtr = json_object_get_uint64(
1071 json_object_object_get(registers, "gdtr"));
1072 register_state.Gdtr[0] = gdtr & 0xFFFFFFFF;
1073 register_state.Gdtr[1] = gdtr >> 32;
1074 UINT64 idtr = json_object_get_uint64(
1075 json_object_object_get(registers, "idtr"));
1076 register_state.Idtr[0] = idtr & 0xFFFFFFFF;
1077 register_state.Idtr[1] = idtr >> 32;
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001078
Lawrence Tange407b4c2022-07-21 13:54:01 +01001079 //16-bit registers.
1080 register_state.Ldtr = (UINT16)json_object_get_uint64(
1081 json_object_object_get(registers, "ldtr"));
1082 register_state.Tr = (UINT16)json_object_get_uint64(
1083 json_object_object_get(registers, "tr"));
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001084
Lawrence Tange407b4c2022-07-21 13:54:01 +01001085 //Write out to stream.
1086 fwrite(&register_state, sizeof(EFI_CONTEXT_IA32_REGISTER_STATE), 1,
1087 out);
1088 fflush(out);
Lawrence Tangd0c88842022-07-13 14:51:17 +01001089}
1090
1091//Converts a single CPER-JSON x64 register array into CPER binary, outputting to the given stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +01001092void ir_ia32x64_x64_registers_to_cper(json_object *registers, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +01001093{
Lawrence Tange407b4c2022-07-21 13:54:01 +01001094 EFI_CONTEXT_X64_REGISTER_STATE register_state;
1095 register_state.Rax = json_object_get_uint64(
1096 json_object_object_get(registers, "rax"));
1097 register_state.Rbx = json_object_get_uint64(
1098 json_object_object_get(registers, "rbx"));
1099 register_state.Rcx = json_object_get_uint64(
1100 json_object_object_get(registers, "rcx"));
1101 register_state.Rdx = json_object_get_uint64(
1102 json_object_object_get(registers, "rdx"));
1103 register_state.Rsi = json_object_get_uint64(
1104 json_object_object_get(registers, "rsi"));
1105 register_state.Rdi = json_object_get_uint64(
1106 json_object_object_get(registers, "rdi"));
1107 register_state.Rbp = json_object_get_uint64(
1108 json_object_object_get(registers, "rbp"));
1109 register_state.Rsp = json_object_get_uint64(
1110 json_object_object_get(registers, "rsp"));
1111 register_state.R8 =
1112 json_object_get_uint64(json_object_object_get(registers, "r8"));
1113 register_state.R9 =
1114 json_object_get_uint64(json_object_object_get(registers, "r9"));
1115 register_state.R10 = json_object_get_uint64(
1116 json_object_object_get(registers, "r10"));
1117 register_state.R11 = json_object_get_uint64(
1118 json_object_object_get(registers, "r11"));
1119 register_state.R12 = json_object_get_uint64(
1120 json_object_object_get(registers, "r12"));
1121 register_state.R13 = json_object_get_uint64(
1122 json_object_object_get(registers, "r13"));
1123 register_state.R14 = json_object_get_uint64(
1124 json_object_object_get(registers, "r14"));
1125 register_state.R15 = json_object_get_uint64(
1126 json_object_object_get(registers, "r15"));
1127 register_state.Cs = (UINT16)json_object_get_int(
1128 json_object_object_get(registers, "cs"));
1129 register_state.Ds = (UINT16)json_object_get_int(
1130 json_object_object_get(registers, "ds"));
1131 register_state.Ss = (UINT16)json_object_get_int(
1132 json_object_object_get(registers, "ss"));
1133 register_state.Es = (UINT16)json_object_get_int(
1134 json_object_object_get(registers, "es"));
1135 register_state.Fs = (UINT16)json_object_get_int(
1136 json_object_object_get(registers, "fs"));
1137 register_state.Gs = (UINT16)json_object_get_int(
1138 json_object_object_get(registers, "gs"));
1139 register_state.Resv1 = 0;
1140 register_state.Rflags = json_object_get_uint64(
1141 json_object_object_get(registers, "rflags"));
1142 register_state.Rip = json_object_get_uint64(
1143 json_object_object_get(registers, "eip"));
1144 register_state.Cr0 = json_object_get_uint64(
1145 json_object_object_get(registers, "cr0"));
1146 register_state.Cr1 = json_object_get_uint64(
1147 json_object_object_get(registers, "cr1"));
1148 register_state.Cr2 = json_object_get_uint64(
1149 json_object_object_get(registers, "cr2"));
1150 register_state.Cr3 = json_object_get_uint64(
1151 json_object_object_get(registers, "cr3"));
1152 register_state.Cr4 = json_object_get_uint64(
1153 json_object_object_get(registers, "cr4"));
1154 register_state.Cr8 = json_object_get_uint64(
1155 json_object_object_get(registers, "cr8"));
1156 register_state.Gdtr[0] = json_object_get_uint64(
1157 json_object_object_get(registers, "gdtr_0"));
1158 register_state.Gdtr[1] = json_object_get_uint64(
1159 json_object_object_get(registers, "gdtr_1"));
1160 register_state.Idtr[0] = json_object_get_uint64(
1161 json_object_object_get(registers, "idtr_0"));
1162 register_state.Idtr[1] = json_object_get_uint64(
1163 json_object_object_get(registers, "idtr_1"));
1164 register_state.Ldtr = (UINT16)json_object_get_int(
1165 json_object_object_get(registers, "ldtr"));
1166 register_state.Tr = (UINT16)json_object_get_int(
1167 json_object_object_get(registers, "tr"));
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001168
Lawrence Tange407b4c2022-07-21 13:54:01 +01001169 //Write out to stream.
1170 fwrite(&register_state, sizeof(EFI_CONTEXT_X64_REGISTER_STATE), 1, out);
1171 fflush(out);
John Chungf8fc7052024-05-03 20:05:29 +08001172}