blob: fe3acca6d728f7fa3185edb7d09c48b79eddd055 [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
Ed Tanous1a648562025-03-10 15:23:38 -0700146EFI_GUID *gEfiIa32x64ErrorTypeGuids[] = {
147 &gEfiIa32x64ErrorTypeCacheCheckGuid,
148 &gEfiIa32x64ErrorTypeTlbCheckGuid,
149 &gEfiIa32x64ErrorTypeBusCheckGuid,
150 &gEfiIa32x64ErrorTypeMsCheckGuid,
151};
152
Lawrence Tang794312c2022-07-05 14:46:10 +0100153//Converts a single IA32/x64 processor error info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100154json_object *cper_ia32x64_processor_error_info_to_ir(
155 EFI_IA32_X64_PROCESS_ERROR_INFO *error_info)
Lawrence Tang794312c2022-07-05 14:46:10 +0100156{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100157 json_object *error_info_ir = json_object_new_object();
Ed Tanousc2ebddd2025-03-09 10:07:01 -0700158 json_object *type = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +0100159
Lawrence Tange407b4c2022-07-21 13:54:01 +0100160 //Error structure type (as GUID).
Ed Tanousc2ebddd2025-03-09 10:07:01 -0700161 add_guid(type, "guid", &error_info->ErrorType);
Lawrence Tang794312c2022-07-05 14:46:10 +0100162
Lawrence Tang3592da72022-07-21 16:50:07 +0100163 //Get the error structure type as a readable string.
164 const char *readable_type = "Unknown";
Ed Tanous1a648562025-03-10 15:23:38 -0700165
166 const char *readable_names[] = {
167 "Cache Check Error",
168 "TLB Check Error",
169 "Bus Check Error",
170 "MS Check Error",
171 };
172
173 int index = select_guid_from_list(
174 &error_info->ErrorType, gEfiIa32x64ErrorTypeGuids,
175 sizeof(gEfiIa32x64ErrorTypeGuids) / sizeof(EFI_GUID *));
176
177 if (index < (int)(sizeof(readable_names) / sizeof(char *))) {
178 readable_type = readable_names[index];
John Chungf8fc7052024-05-03 20:05:29 +0800179 }
Ed Tanous1a648562025-03-10 15:23:38 -0700180
John Chungf8fc7052024-05-03 20:05:29 +0800181 json_object_object_add(type, "name",
182 json_object_new_string(readable_type));
Lawrence Tang3592da72022-07-21 16:50:07 +0100183 json_object_object_add(error_info_ir, "type", type);
184
Lawrence Tange407b4c2022-07-21 13:54:01 +0100185 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800186 ValidationTypes ui64Type = { UINT_64T,
187 .value.ui64 = error_info->ValidFields };
Lawrence Tang794312c2022-07-05 14:46:10 +0100188
Lawrence Tange407b4c2022-07-21 13:54:01 +0100189 //Add the check information on a per-structure basis.
190 //Cache and TLB check information are identical, so can be equated.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800191 if (isvalid_prop_to_ir(&ui64Type, 0)) {
192 json_object *check_information = NULL;
Ed Tanous1a648562025-03-10 15:23:38 -0700193
194 switch (index) {
195 case 0:
196 case 1:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800197 check_information = cper_ia32x64_cache_tlb_check_to_ir(
198 (EFI_IA32_X64_CACHE_CHECK_INFO *)&error_info
199 ->CheckInfo);
Ed Tanous1a648562025-03-10 15:23:38 -0700200 break;
201 case 2:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800202 check_information = cper_ia32x64_bus_check_to_ir(
203 (EFI_IA32_X64_BUS_CHECK_INFO *)&error_info
204 ->CheckInfo);
Ed Tanous1a648562025-03-10 15:23:38 -0700205 break;
206 case 3:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800207 check_information = cper_ia32x64_ms_check_to_ir(
208 (EFI_IA32_X64_MS_CHECK_INFO *)&error_info
209 ->CheckInfo);
Ed Tanous1a648562025-03-10 15:23:38 -0700210 break;
211 default:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800212 //Unknown check information.
213 printf("WARN: Invalid/unknown check information GUID found in IA32/x64 CPER section. Ignoring.\n");
Ed Tanous1a648562025-03-10 15:23:38 -0700214 break;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800215 }
Ed Tanous1a648562025-03-10 15:23:38 -0700216
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800217 json_object_object_add(error_info_ir, "checkInfo",
218 check_information);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100219 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100220
Lawrence Tange407b4c2022-07-21 13:54:01 +0100221 //Target, requestor, and responder identifiers.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800222 if (isvalid_prop_to_ir(&ui64Type, 1)) {
223 json_object_object_add(
224 error_info_ir, "targetAddressID",
225 json_object_new_uint64(error_info->TargetId));
226 }
227 if (isvalid_prop_to_ir(&ui64Type, 2)) {
228 json_object_object_add(
229 error_info_ir, "requestorID",
230 json_object_new_uint64(error_info->RequestorId));
231 }
232 if (isvalid_prop_to_ir(&ui64Type, 3)) {
233 json_object_object_add(
234 error_info_ir, "responderID",
235 json_object_new_uint64(error_info->ResponderId));
236 }
237 if (isvalid_prop_to_ir(&ui64Type, 4)) {
238 json_object_object_add(
239 error_info_ir, "instructionPointer",
240 json_object_new_uint64(error_info->InstructionIP));
241 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100242
Lawrence Tange407b4c2022-07-21 13:54:01 +0100243 return error_info_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100244}
245
246//Converts a single IA32/x64 cache or TLB check check info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100247json_object *cper_ia32x64_cache_tlb_check_to_ir(
248 EFI_IA32_X64_CACHE_CHECK_INFO *cache_tlb_check)
Lawrence Tang794312c2022-07-05 14:46:10 +0100249{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100250 json_object *cache_tlb_check_ir = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +0100251
Lawrence Tange407b4c2022-07-21 13:54:01 +0100252 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800253 ValidationTypes ui64Type = {
254 UINT_64T, .value.ui64 = cache_tlb_check->ValidFields
255 };
Lawrence Tang794312c2022-07-05 14:46:10 +0100256
Lawrence Tange407b4c2022-07-21 13:54:01 +0100257 //Transaction type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800258 if (isvalid_prop_to_ir(&ui64Type, 0)) {
259 json_object *transaction_type = integer_to_readable_pair(
260 cache_tlb_check->TransactionType, 3,
261 IA32X64_CHECK_INFO_TRANSACTION_TYPES_KEYS,
262 IA32X64_CHECK_INFO_TRANSACTION_TYPES_VALUES,
263 "Unknown (Reserved)");
264 json_object_object_add(cache_tlb_check_ir, "transactionType",
265 transaction_type);
266 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100267
Lawrence Tange407b4c2022-07-21 13:54:01 +0100268 //Operation.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800269 if (isvalid_prop_to_ir(&ui64Type, 1)) {
270 json_object *operation = integer_to_readable_pair(
271 cache_tlb_check->Operation, 9,
272 IA32X64_CHECK_INFO_OPERATION_TYPES_KEYS,
273 IA32X64_CHECK_INFO_OPERATION_TYPES_VALUES,
274 "Unknown (Reserved)");
275 json_object_object_add(cache_tlb_check_ir, "operation",
276 operation);
277 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100278
Lawrence Tange407b4c2022-07-21 13:54:01 +0100279 //Affected cache/TLB level.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800280 if (isvalid_prop_to_ir(&ui64Type, 2)) {
281 json_object_object_add(
282 cache_tlb_check_ir, "level",
283 json_object_new_uint64(cache_tlb_check->Level));
284 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100285
Lawrence Tange407b4c2022-07-21 13:54:01 +0100286 //Miscellaneous boolean fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800287 if (isvalid_prop_to_ir(&ui64Type, 3)) {
288 json_object_object_add(
289 cache_tlb_check_ir, "processorContextCorrupt",
290 json_object_new_boolean(
291 cache_tlb_check->ContextCorrupt));
292 }
293 if (isvalid_prop_to_ir(&ui64Type, 4)) {
294 json_object_object_add(
295 cache_tlb_check_ir, "uncorrected",
296 json_object_new_boolean(
297 cache_tlb_check->ErrorUncorrected));
298 }
299 if (isvalid_prop_to_ir(&ui64Type, 5)) {
300 json_object_object_add(
301 cache_tlb_check_ir, "preciseIP",
302 json_object_new_boolean(cache_tlb_check->PreciseIp));
303 }
304 if (isvalid_prop_to_ir(&ui64Type, 6)) {
305 json_object_object_add(cache_tlb_check_ir, "restartableIP",
306 json_object_new_boolean(
307 cache_tlb_check->RestartableIp));
308 }
309 if (isvalid_prop_to_ir(&ui64Type, 7)) {
310 json_object_object_add(
311 cache_tlb_check_ir, "overflow",
312 json_object_new_boolean(cache_tlb_check->Overflow));
313 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100314
Lawrence Tange407b4c2022-07-21 13:54:01 +0100315 return cache_tlb_check_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100316}
317
318//Converts a single IA32/x64 bus check check info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100319json_object *
320cper_ia32x64_bus_check_to_ir(EFI_IA32_X64_BUS_CHECK_INFO *bus_check)
321{
322 json_object *bus_check_ir = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +0100323
Lawrence Tange407b4c2022-07-21 13:54:01 +0100324 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800325 ValidationTypes ui64Type = { UINT_64T,
326 .value.ui64 = bus_check->ValidFields };
Lawrence Tang794312c2022-07-05 14:46:10 +0100327
Lawrence Tange407b4c2022-07-21 13:54:01 +0100328 //Transaction type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800329 if (isvalid_prop_to_ir(&ui64Type, 0)) {
330 json_object *transaction_type = integer_to_readable_pair(
331 bus_check->TransactionType, 3,
332 IA32X64_CHECK_INFO_TRANSACTION_TYPES_KEYS,
333 IA32X64_CHECK_INFO_TRANSACTION_TYPES_VALUES,
334 "Unknown (Reserved)");
335 json_object_object_add(bus_check_ir, "transactionType",
336 transaction_type);
337 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100338
Lawrence Tange407b4c2022-07-21 13:54:01 +0100339 //Operation.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800340 if (isvalid_prop_to_ir(&ui64Type, 1)) {
341 json_object *operation = integer_to_readable_pair(
342 bus_check->Operation, 9,
343 IA32X64_CHECK_INFO_OPERATION_TYPES_KEYS,
344 IA32X64_CHECK_INFO_OPERATION_TYPES_VALUES,
345 "Unknown (Reserved)");
346 json_object_object_add(bus_check_ir, "operation", operation);
347 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100348
Lawrence Tange407b4c2022-07-21 13:54:01 +0100349 //Affected bus level.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800350 if (isvalid_prop_to_ir(&ui64Type, 2)) {
351 json_object_object_add(
352 bus_check_ir, "level",
353 json_object_new_uint64(bus_check->Level));
354 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100355
Lawrence Tange407b4c2022-07-21 13:54:01 +0100356 //Miscellaneous boolean fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800357 if (isvalid_prop_to_ir(&ui64Type, 3)) {
358 json_object_object_add(
359 bus_check_ir, "processorContextCorrupt",
360 json_object_new_boolean(bus_check->ContextCorrupt));
361 }
362 if (isvalid_prop_to_ir(&ui64Type, 4)) {
363 json_object_object_add(
364 bus_check_ir, "uncorrected",
365 json_object_new_boolean(bus_check->ErrorUncorrected));
366 }
367 if (isvalid_prop_to_ir(&ui64Type, 5)) {
368 json_object_object_add(
369 bus_check_ir, "preciseIP",
370 json_object_new_boolean(bus_check->PreciseIp));
371 }
372 if (isvalid_prop_to_ir(&ui64Type, 6)) {
373 json_object_object_add(
374 bus_check_ir, "restartableIP",
375 json_object_new_boolean(bus_check->RestartableIp));
376 }
377 if (isvalid_prop_to_ir(&ui64Type, 7)) {
378 json_object_object_add(
379 bus_check_ir, "overflow",
380 json_object_new_boolean(bus_check->Overflow));
381 }
382 if (isvalid_prop_to_ir(&ui64Type, 9)) {
383 json_object_object_add(
384 bus_check_ir, "timedOut",
385 json_object_new_boolean(bus_check->TimeOut));
386 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100387
Lawrence Tange407b4c2022-07-21 13:54:01 +0100388 //Participation type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800389 if (isvalid_prop_to_ir(&ui64Type, 8)) {
390 json_object *participation_type = integer_to_readable_pair(
391 bus_check->ParticipationType, 4,
392 IA32X64_BUS_CHECK_INFO_PARTICIPATION_TYPES_KEYS,
393 IA32X64_BUS_CHECK_INFO_PARTICIPATION_TYPES_VALUES,
394 "Unknown");
395 json_object_object_add(bus_check_ir, "participationType",
396 participation_type);
397 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100398
Lawrence Tange407b4c2022-07-21 13:54:01 +0100399 //Address space.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800400 if (isvalid_prop_to_ir(&ui64Type, 10)) {
401 json_object *address_space = integer_to_readable_pair(
402 bus_check->AddressSpace, 4,
403 IA32X64_BUS_CHECK_INFO_ADDRESS_SPACE_TYPES_KEYS,
404 IA32X64_BUS_CHECK_INFO_ADDRESS_SPACE_TYPES_VALUES,
405 "Unknown");
406 json_object_object_add(bus_check_ir, "addressSpace",
407 address_space);
408 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100409
410 return bus_check_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100411}
412
413//Converts a single IA32/x64 MS check check info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100414json_object *cper_ia32x64_ms_check_to_ir(EFI_IA32_X64_MS_CHECK_INFO *ms_check)
Lawrence Tang794312c2022-07-05 14:46:10 +0100415{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100416 json_object *ms_check_ir = json_object_new_object();
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800417 ValidationTypes ui64Type = { UINT_64T,
418 .value.ui64 = ms_check->ValidFields };
Lawrence Tange407b4c2022-07-21 13:54:01 +0100419 //Validation bits.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100420 //Error type (operation that caused the error).
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800421 if (isvalid_prop_to_ir(&ui64Type, 0)) {
422 json_object *error_type = integer_to_readable_pair(
423 ms_check->ErrorType, 4,
424 IA32X64_MS_CHECK_INFO_ERROR_TYPES_KEYS,
425 IA32X64_MS_CHECK_INFO_ERROR_TYPES_VALUES,
426 "Unknown (Processor Specific)");
427 json_object_object_add(ms_check_ir, "errorType", error_type);
428 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100429
Lawrence Tange407b4c2022-07-21 13:54:01 +0100430 //Miscellaneous fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800431 if (isvalid_prop_to_ir(&ui64Type, 1)) {
432 json_object_object_add(
433 ms_check_ir, "processorContextCorrupt",
434 json_object_new_boolean(ms_check->ContextCorrupt));
435 }
436 if (isvalid_prop_to_ir(&ui64Type, 2)) {
437 json_object_object_add(
438 ms_check_ir, "uncorrected",
439 json_object_new_boolean(ms_check->ErrorUncorrected));
440 }
441 if (isvalid_prop_to_ir(&ui64Type, 3)) {
442 json_object_object_add(
443 ms_check_ir, "preciseIP",
444 json_object_new_boolean(ms_check->PreciseIp));
445 }
446 if (isvalid_prop_to_ir(&ui64Type, 4)) {
447 json_object_object_add(
448 ms_check_ir, "restartableIP",
449 json_object_new_boolean(ms_check->RestartableIp));
450 }
451 if (isvalid_prop_to_ir(&ui64Type, 5)) {
452 json_object_object_add(
453 ms_check_ir, "overflow",
454 json_object_new_boolean(ms_check->Overflow));
455 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100456
457 return ms_check_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100458}
459
460//Converts a single IA32/x64 processor context info entry into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100461json_object *cper_ia32x64_processor_context_info_to_ir(
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800462 EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *context_info, void **cur_pos,
463 UINT32 *remaining_size)
Lawrence Tang794312c2022-07-05 14:46:10 +0100464{
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800465 if (*remaining_size < sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO)) {
466 return NULL;
467 }
468 *remaining_size -= sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100469 json_object *context_info_ir = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +0100470
Lawrence Tange407b4c2022-07-21 13:54:01 +0100471 //Register context type.
472 json_object *context_type = integer_to_readable_pair(
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800473 context_info->RegisterType, IA32X64_REGISTER_CONTEXT_TYPES_SIZE,
Lawrence Tange407b4c2022-07-21 13:54:01 +0100474 IA32X64_REGISTER_CONTEXT_TYPES_KEYS,
475 IA32X64_REGISTER_CONTEXT_TYPES_VALUES, "Unknown (Reserved)");
476 json_object_object_add(context_info_ir, "registerContextType",
477 context_type);
Lawrence Tang794312c2022-07-05 14:46:10 +0100478
Lawrence Tange407b4c2022-07-21 13:54:01 +0100479 //Register array size, MSR and MM address.
480 json_object_object_add(context_info_ir, "registerArraySize",
481 json_object_new_uint64(context_info->ArraySize));
482 json_object_object_add(
483 context_info_ir, "msrAddress",
484 json_object_new_uint64(context_info->MsrAddress));
485 json_object_object_add(
486 context_info_ir, "mmRegisterAddress",
487 json_object_new_uint64(context_info->MmRegisterAddress));
Lawrence Tang794312c2022-07-05 14:46:10 +0100488
Lawrence Tange407b4c2022-07-21 13:54:01 +0100489 //Register array.
490 json_object *register_array = NULL;
491 if (context_info->RegisterType == EFI_REG_CONTEXT_TYPE_IA32) {
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800492 if (*remaining_size < sizeof(EFI_CONTEXT_IA32_REGISTER_STATE)) {
493 json_object_put(context_info_ir);
494 return NULL;
495 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100496 EFI_CONTEXT_IA32_REGISTER_STATE *register_state =
497 (EFI_CONTEXT_IA32_REGISTER_STATE *)(context_info + 1);
498 register_array =
499 cper_ia32x64_register_32bit_to_ir(register_state);
500 *cur_pos = (void *)(register_state + 1);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800501 *remaining_size -= sizeof(EFI_CONTEXT_IA32_REGISTER_STATE);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100502 } else if (context_info->RegisterType == EFI_REG_CONTEXT_TYPE_X64) {
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800503 if (*remaining_size < sizeof(EFI_CONTEXT_X64_REGISTER_STATE)) {
504 json_object_put(context_info_ir);
505 return NULL;
506 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100507 EFI_CONTEXT_X64_REGISTER_STATE *register_state =
508 (EFI_CONTEXT_X64_REGISTER_STATE *)(context_info + 1);
509 register_array =
510 cper_ia32x64_register_64bit_to_ir(register_state);
511 *cur_pos = (void *)(register_state + 1);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800512 *remaining_size -= sizeof(EFI_CONTEXT_X64_REGISTER_STATE);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100513 } else {
514 //No parseable data, just dump as base64 and shift the head to the next item.
515 *cur_pos = (void *)(context_info + 1);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800516 if (*remaining_size < context_info->ArraySize) {
517 json_object_put(context_info_ir);
518 return NULL;
519 }
Ed Tanousa7d2cdd2024-07-15 11:07:27 -0700520 int32_t encoded_len = 0;
521 char *encoded = base64_encode((UINT8 *)*cur_pos,
522 context_info->ArraySize,
523 &encoded_len);
524 if (encoded == NULL) {
John Chungf8fc7052024-05-03 20:05:29 +0800525 printf("Failed to allocate encode output buffer. \n");
526 } else {
John Chungf8fc7052024-05-03 20:05:29 +0800527 register_array = json_object_new_object();
528 json_object_object_add(register_array, "data",
529 json_object_new_string_len(
530 encoded, encoded_len));
531 free(encoded);
532 }
Lawrence Tangd7e8ca32022-07-07 10:25:53 +0100533
Lawrence Tange407b4c2022-07-21 13:54:01 +0100534 *cur_pos =
535 (void *)(((char *)*cur_pos) + context_info->ArraySize);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800536 *remaining_size -= context_info->ArraySize;
Lawrence Tange407b4c2022-07-21 13:54:01 +0100537 }
538 json_object_object_add(context_info_ir, "registerArray",
539 register_array);
Lawrence Tang794312c2022-07-05 14:46:10 +0100540
Lawrence Tange407b4c2022-07-21 13:54:01 +0100541 return context_info_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100542}
543
544//Converts a single CPER IA32 register state into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100545json_object *
546cper_ia32x64_register_32bit_to_ir(EFI_CONTEXT_IA32_REGISTER_STATE *registers)
Lawrence Tang794312c2022-07-05 14:46:10 +0100547{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100548 json_object *ia32_registers = json_object_new_object();
549 json_object_object_add(ia32_registers, "eax",
550 json_object_new_uint64(registers->Eax));
551 json_object_object_add(ia32_registers, "ebx",
552 json_object_new_uint64(registers->Ebx));
553 json_object_object_add(ia32_registers, "ecx",
554 json_object_new_uint64(registers->Ecx));
555 json_object_object_add(ia32_registers, "edx",
556 json_object_new_uint64(registers->Edx));
557 json_object_object_add(ia32_registers, "esi",
558 json_object_new_uint64(registers->Esi));
559 json_object_object_add(ia32_registers, "edi",
560 json_object_new_uint64(registers->Edi));
561 json_object_object_add(ia32_registers, "ebp",
562 json_object_new_uint64(registers->Ebp));
563 json_object_object_add(ia32_registers, "esp",
564 json_object_new_uint64(registers->Esp));
565 json_object_object_add(ia32_registers, "cs",
566 json_object_new_uint64(registers->Cs));
567 json_object_object_add(ia32_registers, "ds",
568 json_object_new_uint64(registers->Ds));
569 json_object_object_add(ia32_registers, "ss",
570 json_object_new_uint64(registers->Ss));
571 json_object_object_add(ia32_registers, "es",
572 json_object_new_uint64(registers->Es));
573 json_object_object_add(ia32_registers, "fs",
574 json_object_new_uint64(registers->Fs));
575 json_object_object_add(ia32_registers, "gs",
576 json_object_new_uint64(registers->Gs));
577 json_object_object_add(ia32_registers, "eflags",
578 json_object_new_uint64(registers->Eflags));
579 json_object_object_add(ia32_registers, "eip",
580 json_object_new_uint64(registers->Eip));
581 json_object_object_add(ia32_registers, "cr0",
582 json_object_new_uint64(registers->Cr0));
583 json_object_object_add(ia32_registers, "cr1",
584 json_object_new_uint64(registers->Cr1));
585 json_object_object_add(ia32_registers, "cr2",
586 json_object_new_uint64(registers->Cr2));
587 json_object_object_add(ia32_registers, "cr3",
588 json_object_new_uint64(registers->Cr3));
589 json_object_object_add(ia32_registers, "cr4",
590 json_object_new_uint64(registers->Cr4));
591 json_object_object_add(
592 ia32_registers, "gdtr",
593 json_object_new_uint64(registers->Gdtr[0] +
594 ((UINT64)registers->Gdtr[1] << 32)));
595 json_object_object_add(
596 ia32_registers, "idtr",
597 json_object_new_uint64(registers->Idtr[0] +
598 ((UINT64)registers->Idtr[1] << 32)));
599 json_object_object_add(ia32_registers, "ldtr",
600 json_object_new_uint64(registers->Ldtr));
601 json_object_object_add(ia32_registers, "tr",
602 json_object_new_uint64(registers->Tr));
Lawrence Tang794312c2022-07-05 14:46:10 +0100603
Lawrence Tange407b4c2022-07-21 13:54:01 +0100604 return ia32_registers;
Lawrence Tang794312c2022-07-05 14:46:10 +0100605}
606
607//Converts a single CPER x64 register state into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100608json_object *
609cper_ia32x64_register_64bit_to_ir(EFI_CONTEXT_X64_REGISTER_STATE *registers)
Lawrence Tang794312c2022-07-05 14:46:10 +0100610{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100611 json_object *x64_registers = json_object_new_object();
612 json_object_object_add(x64_registers, "rax",
613 json_object_new_uint64(registers->Rax));
614 json_object_object_add(x64_registers, "rbx",
615 json_object_new_uint64(registers->Rbx));
616 json_object_object_add(x64_registers, "rcx",
617 json_object_new_uint64(registers->Rcx));
618 json_object_object_add(x64_registers, "rdx",
619 json_object_new_uint64(registers->Rdx));
620 json_object_object_add(x64_registers, "rsi",
621 json_object_new_uint64(registers->Rsi));
622 json_object_object_add(x64_registers, "rdi",
623 json_object_new_uint64(registers->Rdi));
624 json_object_object_add(x64_registers, "rbp",
625 json_object_new_uint64(registers->Rbp));
626 json_object_object_add(x64_registers, "rsp",
627 json_object_new_uint64(registers->Rsp));
628 json_object_object_add(x64_registers, "r8",
629 json_object_new_uint64(registers->R8));
630 json_object_object_add(x64_registers, "r9",
631 json_object_new_uint64(registers->R9));
632 json_object_object_add(x64_registers, "r10",
633 json_object_new_uint64(registers->R10));
634 json_object_object_add(x64_registers, "r11",
635 json_object_new_uint64(registers->R11));
636 json_object_object_add(x64_registers, "r12",
637 json_object_new_uint64(registers->R12));
638 json_object_object_add(x64_registers, "r13",
639 json_object_new_uint64(registers->R13));
640 json_object_object_add(x64_registers, "r14",
641 json_object_new_uint64(registers->R14));
642 json_object_object_add(x64_registers, "r15",
643 json_object_new_uint64(registers->R15));
644 json_object_object_add(x64_registers, "cs",
645 json_object_new_int(registers->Cs));
646 json_object_object_add(x64_registers, "ds",
647 json_object_new_int(registers->Ds));
648 json_object_object_add(x64_registers, "ss",
649 json_object_new_int(registers->Ss));
650 json_object_object_add(x64_registers, "es",
651 json_object_new_int(registers->Es));
652 json_object_object_add(x64_registers, "fs",
653 json_object_new_int(registers->Fs));
654 json_object_object_add(x64_registers, "gs",
655 json_object_new_int(registers->Gs));
656 json_object_object_add(x64_registers, "rflags",
657 json_object_new_uint64(registers->Rflags));
658 json_object_object_add(x64_registers, "eip",
659 json_object_new_uint64(registers->Rip));
660 json_object_object_add(x64_registers, "cr0",
661 json_object_new_uint64(registers->Cr0));
662 json_object_object_add(x64_registers, "cr1",
663 json_object_new_uint64(registers->Cr1));
664 json_object_object_add(x64_registers, "cr2",
665 json_object_new_uint64(registers->Cr2));
666 json_object_object_add(x64_registers, "cr3",
667 json_object_new_uint64(registers->Cr3));
668 json_object_object_add(x64_registers, "cr4",
669 json_object_new_uint64(registers->Cr4));
670 json_object_object_add(x64_registers, "cr8",
671 json_object_new_uint64(registers->Cr8));
672 json_object_object_add(x64_registers, "gdtr_0",
673 json_object_new_uint64(registers->Gdtr[0]));
674 json_object_object_add(x64_registers, "gdtr_1",
675 json_object_new_uint64(registers->Gdtr[1]));
676 json_object_object_add(x64_registers, "idtr_0",
677 json_object_new_uint64(registers->Idtr[0]));
678 json_object_object_add(x64_registers, "idtr_1",
679 json_object_new_uint64(registers->Idtr[1]));
680 json_object_object_add(x64_registers, "ldtr",
681 json_object_new_int(registers->Ldtr));
682 json_object_object_add(x64_registers, "tr",
683 json_object_new_int(registers->Tr));
Lawrence Tang794312c2022-07-05 14:46:10 +0100684
Lawrence Tange407b4c2022-07-21 13:54:01 +0100685 return x64_registers;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100686}
687
688//////////////////
689/// IR TO CPER ///
690//////////////////
691
692//Converts a single IA32/x64 CPER-JSON section into CPER binary, outputting to the provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100693void ir_section_ia32x64_to_cper(json_object *section, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100694{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100695 EFI_IA32_X64_PROCESSOR_ERROR_RECORD *section_cper =
696 (EFI_IA32_X64_PROCESSOR_ERROR_RECORD *)calloc(
697 1, sizeof(EFI_IA32_X64_PROCESSOR_ERROR_RECORD));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100698
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800699 uint64_t valid = 0x0;
700
701 int proc_error_info_num = json_object_get_int(json_object_object_get(
702 section, "processorErrorInfoNum")) &
703 0x3F;
704 int proc_ctx_info_num = json_object_get_int(json_object_object_get(
705 section, "processorContextInfoNum")) &
706 0x3F;
707 valid |= proc_error_info_num << 2;
708 valid |= proc_ctx_info_num << 8;
709
710 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = valid };
711 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100712
Lawrence Tange407b4c2022-07-21 13:54:01 +0100713 //Local APIC ID.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800714 if (json_object_object_get_ex(section, "localAPICID", &obj)) {
715 section_cper->ApicId = json_object_get_uint64(obj);
716 add_to_valid_bitfield(&ui64Type, 0);
717 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100718
Lawrence Tange407b4c2022-07-21 13:54:01 +0100719 //CPUID info.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800720 if (json_object_object_get_ex(section, "cpuidInfo", &obj)) {
721 json_object *cpuid_info = obj;
722 EFI_IA32_X64_CPU_ID *cpuid_info_cper =
723 (EFI_IA32_X64_CPU_ID *)section_cper->CpuIdInfo;
724 cpuid_info_cper->Eax = json_object_get_uint64(
725 json_object_object_get(cpuid_info, "eax"));
726 cpuid_info_cper->Ebx = json_object_get_uint64(
727 json_object_object_get(cpuid_info, "ebx"));
728 cpuid_info_cper->Ecx = json_object_get_uint64(
729 json_object_object_get(cpuid_info, "ecx"));
730 cpuid_info_cper->Edx = json_object_get_uint64(
731 json_object_object_get(cpuid_info, "edx"));
732 add_to_valid_bitfield(&ui64Type, 1);
733 }
734 section_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100735
Lawrence Tange407b4c2022-07-21 13:54:01 +0100736 //Flush the header to file before dealing w/ info sections.
737 fwrite(section_cper, sizeof(EFI_IA32_X64_PROCESSOR_ERROR_RECORD), 1,
738 out);
739 fflush(out);
740 free(section_cper);
741
742 //Iterate and deal with sections.
743 json_object *error_info =
744 json_object_object_get(section, "processorErrorInfo");
745 json_object *context_info =
746 json_object_object_get(section, "processorContextInfo");
John Chungf8fc7052024-05-03 20:05:29 +0800747 for (int i = 0; i < proc_error_info_num; i++) {
Lawrence Tange407b4c2022-07-21 13:54:01 +0100748 ir_ia32x64_error_info_to_cper(
749 json_object_array_get_idx(error_info, i), out);
John Chungf8fc7052024-05-03 20:05:29 +0800750 }
751 for (int i = 0; i < proc_ctx_info_num; i++) {
Lawrence Tange407b4c2022-07-21 13:54:01 +0100752 ir_ia32x64_context_info_to_cper(
753 json_object_array_get_idx(context_info, i), out);
John Chungf8fc7052024-05-03 20:05:29 +0800754 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100755}
756
757//Converts a single CPER-JSON IA32/x64 error information structure into CPER binary, outputting to the
758//provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100759void ir_ia32x64_error_info_to_cper(json_object *error_info, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100760{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100761 EFI_IA32_X64_PROCESS_ERROR_INFO *error_info_cper =
762 (EFI_IA32_X64_PROCESS_ERROR_INFO *)calloc(
763 1, sizeof(EFI_IA32_X64_PROCESS_ERROR_INFO));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100764
Lawrence Tange407b4c2022-07-21 13:54:01 +0100765 //Error structure type.
Lawrence Tang3592da72022-07-21 16:50:07 +0100766 json_object *type = json_object_object_get(error_info, "type");
767 string_to_guid(
768 &error_info_cper->ErrorType,
769 json_object_get_string(json_object_object_get(type, "guid")));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100770
Lawrence Tange407b4c2022-07-21 13:54:01 +0100771 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800772 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
773 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100774
Lawrence Tange407b4c2022-07-21 13:54:01 +0100775 //Check information, parsed based on the error type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800776 if (json_object_object_get_ex(error_info, "checkInfo", &obj)) {
777 json_object *check_info = obj;
Ed Tanous1a648562025-03-10 15:23:38 -0700778
779 int index = select_guid_from_list(
780 &error_info_cper->ErrorType, gEfiIa32x64ErrorTypeGuids,
781 sizeof(gEfiIa32x64ErrorTypeGuids) / sizeof(EFI_GUID *));
782
783 switch (index) {
784 case 0:
785 case 1:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800786 ir_ia32x64_cache_tlb_check_error_to_cper(
787 check_info,
788 (EFI_IA32_X64_CACHE_CHECK_INFO
789 *)&error_info_cper->CheckInfo);
Ed Tanous1a648562025-03-10 15:23:38 -0700790 break;
791 case 2:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800792 ir_ia32x64_bus_check_error_to_cper(
793 check_info,
794 (EFI_IA32_X64_BUS_CHECK_INFO *)&error_info_cper
795 ->CheckInfo);
Ed Tanous1a648562025-03-10 15:23:38 -0700796 break;
797 case 3:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800798 ir_ia32x64_ms_check_error_to_cper(
799 check_info,
800 (EFI_IA32_X64_MS_CHECK_INFO *)&error_info_cper
801 ->CheckInfo);
Ed Tanous1a648562025-03-10 15:23:38 -0700802 break;
803 default:
804 //Unknown check information.
805 printf("WARN: Invalid/unknown check information GUID found in IA32/x64 CPER section. Ignoring.\n");
806 break;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800807 }
808 add_to_valid_bitfield(&ui64Type, 0);
John Chungf8fc7052024-05-03 20:05:29 +0800809 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100810
Lawrence Tange407b4c2022-07-21 13:54:01 +0100811 //Miscellaneous numeric fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800812 if (json_object_object_get_ex(error_info, "targetAddressID", &obj)) {
813 error_info_cper->TargetId = json_object_get_uint64(obj);
814 add_to_valid_bitfield(&ui64Type, 1);
815 }
816 if (json_object_object_get_ex(error_info, "requestorID", &obj)) {
817 error_info_cper->RequestorId = json_object_get_uint64(obj);
818 add_to_valid_bitfield(&ui64Type, 2);
819 }
820 if (json_object_object_get_ex(error_info, "responderID", &obj)) {
821 error_info_cper->ResponderId = json_object_get_uint64(obj);
822 add_to_valid_bitfield(&ui64Type, 3);
823 }
824 if (json_object_object_get_ex(error_info, "instructionPointer", &obj)) {
825 error_info_cper->InstructionIP = json_object_get_uint64(obj);
826 add_to_valid_bitfield(&ui64Type, 4);
827 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100828
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800829 error_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tange407b4c2022-07-21 13:54:01 +0100830 //Write out to stream, then free resources.
831 fwrite(error_info_cper, sizeof(EFI_IA32_X64_PROCESS_ERROR_INFO), 1,
832 out);
833 fflush(out);
834 free(error_info_cper);
Lawrence Tangd0c88842022-07-13 14:51:17 +0100835}
836
837//Converts a single CPER-JSON IA32/x64 cache/TLB check error info structure to CPER binary.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100838void ir_ia32x64_cache_tlb_check_error_to_cper(
839 json_object *check_info, EFI_IA32_X64_CACHE_CHECK_INFO *check_info_cper)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100840{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100841 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800842 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
843 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100844
Lawrence Tange407b4c2022-07-21 13:54:01 +0100845 //Transaction type, operation.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800846 if (json_object_object_get_ex(check_info, "transactionType", &obj)) {
847 check_info_cper->TransactionType =
848 readable_pair_to_integer(obj);
849 add_to_valid_bitfield(&ui64Type, 0);
850 }
851 if (json_object_object_get_ex(check_info, "operation", &obj)) {
852 check_info_cper->Operation = readable_pair_to_integer(obj);
853 add_to_valid_bitfield(&ui64Type, 1);
854 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100855
Lawrence Tange407b4c2022-07-21 13:54:01 +0100856 //Miscellaneous raw value fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800857 if (json_object_object_get_ex(check_info, "level", &obj)) {
858 check_info_cper->Level = json_object_get_uint64(obj);
859 add_to_valid_bitfield(&ui64Type, 2);
860 }
861 if (json_object_object_get_ex(check_info, "processorContextCorrupt",
862 &obj)) {
863 check_info_cper->ContextCorrupt = json_object_get_boolean(obj);
864 add_to_valid_bitfield(&ui64Type, 3);
865 }
866 if (json_object_object_get_ex(check_info, "uncorrected", &obj)) {
867 check_info_cper->ErrorUncorrected =
868 json_object_get_boolean(obj);
869 add_to_valid_bitfield(&ui64Type, 4);
870 }
871 if (json_object_object_get_ex(check_info, "preciseIP", &obj)) {
872 check_info_cper->PreciseIp = json_object_get_boolean(obj);
873 add_to_valid_bitfield(&ui64Type, 5);
874 }
875 if (json_object_object_get_ex(check_info, "restartableIP", &obj)) {
876 check_info_cper->RestartableIp = json_object_get_boolean(obj);
877 add_to_valid_bitfield(&ui64Type, 6);
878 }
879 if (json_object_object_get_ex(check_info, "overflow", &obj)) {
880 check_info_cper->Overflow = json_object_get_boolean(obj);
881 add_to_valid_bitfield(&ui64Type, 7);
882 }
883 check_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100884}
885
886//Converts a single CPER-JSON IA32/x64 bus error info structure to CPER binary.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100887void ir_ia32x64_bus_check_error_to_cper(
888 json_object *check_info, EFI_IA32_X64_BUS_CHECK_INFO *check_info_cper)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100889{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100890 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800891 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
892 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100893
Lawrence Tange407b4c2022-07-21 13:54:01 +0100894 //Readable pair fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800895 if (json_object_object_get_ex(check_info, "transactionType", &obj)) {
896 check_info_cper->TransactionType =
897 readable_pair_to_integer(obj);
898 add_to_valid_bitfield(&ui64Type, 0);
899 }
900 if (json_object_object_get_ex(check_info, "operation", &obj)) {
901 check_info_cper->Operation = readable_pair_to_integer(obj);
902 add_to_valid_bitfield(&ui64Type, 1);
903 }
904 if (json_object_object_get_ex(check_info, "participationType", &obj)) {
905 check_info_cper->ParticipationType =
906 readable_pair_to_integer(obj);
907 add_to_valid_bitfield(&ui64Type, 8);
908 }
909
910 if (json_object_object_get_ex(check_info, "addressSpace", &obj)) {
911 check_info_cper->AddressSpace = readable_pair_to_integer(obj);
912 add_to_valid_bitfield(&ui64Type, 10);
913 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100914
Lawrence Tange407b4c2022-07-21 13:54:01 +0100915 //Miscellaneous raw value fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800916 if (json_object_object_get_ex(check_info, "level", &obj)) {
917 check_info_cper->Level = json_object_get_uint64(obj);
918 add_to_valid_bitfield(&ui64Type, 2);
919 }
920 if (json_object_object_get_ex(check_info, "processorContextCorrupt",
921 &obj)) {
922 check_info_cper->ContextCorrupt = json_object_get_boolean(obj);
923 add_to_valid_bitfield(&ui64Type, 3);
924 }
925 if (json_object_object_get_ex(check_info, "uncorrected", &obj)) {
926 check_info_cper->ErrorUncorrected =
927 json_object_get_boolean(obj);
928 add_to_valid_bitfield(&ui64Type, 4);
929 }
930 if (json_object_object_get_ex(check_info, "preciseIP", &obj)) {
931 check_info_cper->PreciseIp = json_object_get_boolean(obj);
932 add_to_valid_bitfield(&ui64Type, 5);
933 }
934 if (json_object_object_get_ex(check_info, "restartableIP", &obj)) {
935 check_info_cper->RestartableIp = json_object_get_boolean(obj);
936 add_to_valid_bitfield(&ui64Type, 6);
937 }
938 if (json_object_object_get_ex(check_info, "overflow", &obj)) {
939 check_info_cper->Overflow = json_object_get_boolean(obj);
940 add_to_valid_bitfield(&ui64Type, 7);
941 }
942 if (json_object_object_get_ex(check_info, "timedOut", &obj)) {
943 check_info_cper->TimeOut = json_object_get_boolean(obj);
944 add_to_valid_bitfield(&ui64Type, 9);
945 }
946 check_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100947}
948
949//Converts a single CPER-JSON IA32/x64 MS error info structure to CPER binary.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100950void ir_ia32x64_ms_check_error_to_cper(
951 json_object *check_info, EFI_IA32_X64_MS_CHECK_INFO *check_info_cper)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100952{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100953 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800954 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
955 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100956
Lawrence Tange407b4c2022-07-21 13:54:01 +0100957 //Type of MS check error.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800958 if (json_object_object_get_ex(check_info, "errorType", &obj)) {
959 check_info_cper->ErrorType = readable_pair_to_integer(obj);
960 add_to_valid_bitfield(&ui64Type, 0);
961 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100962
Lawrence Tange407b4c2022-07-21 13:54:01 +0100963 //Miscellaneous raw value fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800964 if (json_object_object_get_ex(check_info, "processorContextCorrupt",
965 &obj)) {
966 check_info_cper->ContextCorrupt = json_object_get_boolean(obj);
967 add_to_valid_bitfield(&ui64Type, 1);
968 }
969 if (json_object_object_get_ex(check_info, "uncorrected", &obj)) {
970 check_info_cper->ErrorUncorrected =
971 json_object_get_boolean(obj);
972 add_to_valid_bitfield(&ui64Type, 2);
973 }
974 if (json_object_object_get_ex(check_info, "preciseIP", &obj)) {
975 check_info_cper->PreciseIp = json_object_get_boolean(obj);
976 add_to_valid_bitfield(&ui64Type, 3);
977 }
978 if (json_object_object_get_ex(check_info, "restartableIP", &obj)) {
979 check_info_cper->RestartableIp = json_object_get_boolean(obj);
980 add_to_valid_bitfield(&ui64Type, 4);
981 }
982 if (json_object_object_get_ex(check_info, "overflow", &obj)) {
983 check_info_cper->Overflow = json_object_get_boolean(obj);
984 add_to_valid_bitfield(&ui64Type, 5);
985 }
986 check_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100987}
988
989//Converts a single CPER-JSON IA32/x64 context information structure into CPER binary, outputting to the
990//provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100991void ir_ia32x64_context_info_to_cper(json_object *context_info, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100992{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100993 EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *context_info_cper =
994 (EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *)calloc(
995 1, sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100996
Lawrence Tange407b4c2022-07-21 13:54:01 +0100997 //Register context type.
998 context_info_cper->RegisterType = (UINT16)readable_pair_to_integer(
999 json_object_object_get(context_info, "registerContextType"));
Lawrence Tangd0c88842022-07-13 14:51:17 +01001000
Lawrence Tange407b4c2022-07-21 13:54:01 +01001001 //Miscellaneous numeric fields.
1002 context_info_cper->ArraySize = (UINT16)json_object_get_uint64(
1003 json_object_object_get(context_info, "registerArraySize"));
1004 context_info_cper->MsrAddress = (UINT32)json_object_get_uint64(
1005 json_object_object_get(context_info, "msrAddress"));
1006 context_info_cper->MmRegisterAddress = json_object_get_uint64(
1007 json_object_object_get(context_info, "mmRegisterAddress"));
Lawrence Tangd0c88842022-07-13 14:51:17 +01001008
Lawrence Tange407b4c2022-07-21 13:54:01 +01001009 //Flush header to stream.
1010 fwrite(context_info_cper, sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO),
1011 1, out);
1012 fflush(out);
Lawrence Tangd0c88842022-07-13 14:51:17 +01001013
Lawrence Tange407b4c2022-07-21 13:54:01 +01001014 //Handle the register array, depending on type provided.
1015 json_object *register_array =
1016 json_object_object_get(context_info, "registerArray");
1017 if (context_info_cper->RegisterType == EFI_REG_CONTEXT_TYPE_IA32) {
1018 ir_ia32x64_ia32_registers_to_cper(register_array, out);
1019 } else if (context_info_cper->RegisterType ==
1020 EFI_REG_CONTEXT_TYPE_X64) {
1021 ir_ia32x64_x64_registers_to_cper(register_array, out);
1022 } else {
1023 //Unknown/structure is not defined.
1024 json_object *encoded =
1025 json_object_object_get(register_array, "data");
Ed Tanousa7d2cdd2024-07-15 11:07:27 -07001026 int32_t decoded_len = 0;
1027 const char *j_string = json_object_get_string(encoded);
1028 int j_size = json_object_get_string_len(encoded);
1029 UINT8 *decoded = base64_decode(j_string, j_size, &decoded_len);
1030 if (decoded == NULL) {
John Chungf8fc7052024-05-03 20:05:29 +08001031 printf("Failed to allocate decode output buffer. \n");
1032 } else {
John Chungf8fc7052024-05-03 20:05:29 +08001033 fwrite(decoded, decoded_len, 1, out);
1034 fflush(out);
1035 free(decoded);
1036 }
Lawrence Tange407b4c2022-07-21 13:54:01 +01001037 }
Lawrence Tangd0c88842022-07-13 14:51:17 +01001038
Lawrence Tange407b4c2022-07-21 13:54:01 +01001039 //Free remaining resources.
1040 free(context_info_cper);
Lawrence Tangd0c88842022-07-13 14:51:17 +01001041}
1042
1043//Converts a single CPER-JSON IA32 register array into CPER binary, outputting to the given stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +01001044void ir_ia32x64_ia32_registers_to_cper(json_object *registers, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +01001045{
Lawrence Tange407b4c2022-07-21 13:54:01 +01001046 EFI_CONTEXT_IA32_REGISTER_STATE register_state;
1047 register_state.Eax = (UINT32)json_object_get_uint64(
1048 json_object_object_get(registers, "eax"));
1049 register_state.Ebx = (UINT32)json_object_get_uint64(
1050 json_object_object_get(registers, "ebx"));
1051 register_state.Ecx = (UINT32)json_object_get_uint64(
1052 json_object_object_get(registers, "ecx"));
1053 register_state.Edx = (UINT32)json_object_get_uint64(
1054 json_object_object_get(registers, "edx"));
1055 register_state.Esi = (UINT32)json_object_get_uint64(
1056 json_object_object_get(registers, "esi"));
1057 register_state.Edi = (UINT32)json_object_get_uint64(
1058 json_object_object_get(registers, "edi"));
1059 register_state.Ebp = (UINT32)json_object_get_uint64(
1060 json_object_object_get(registers, "ebp"));
1061 register_state.Esp = (UINT32)json_object_get_uint64(
1062 json_object_object_get(registers, "esp"));
1063 register_state.Cs = (UINT16)json_object_get_uint64(
1064 json_object_object_get(registers, "cs"));
1065 register_state.Ds = (UINT32)json_object_get_uint64(
1066 json_object_object_get(registers, "ds"));
1067 register_state.Ss = (UINT16)json_object_get_uint64(
1068 json_object_object_get(registers, "ss"));
1069 register_state.Es = (UINT16)json_object_get_uint64(
1070 json_object_object_get(registers, "es"));
1071 register_state.Fs = (UINT16)json_object_get_uint64(
1072 json_object_object_get(registers, "fs"));
1073 register_state.Gs = (UINT16)json_object_get_uint64(
1074 json_object_object_get(registers, "gs"));
1075 register_state.Eflags = (UINT32)json_object_get_uint64(
1076 json_object_object_get(registers, "eflags"));
1077 register_state.Eip = (UINT32)json_object_get_uint64(
1078 json_object_object_get(registers, "eip"));
1079 register_state.Cr0 = (UINT32)json_object_get_uint64(
1080 json_object_object_get(registers, "cr0"));
1081 register_state.Cr1 = (UINT32)json_object_get_uint64(
1082 json_object_object_get(registers, "cr1"));
1083 register_state.Cr2 = (UINT32)json_object_get_uint64(
1084 json_object_object_get(registers, "cr2"));
1085 register_state.Cr3 = (UINT32)json_object_get_uint64(
1086 json_object_object_get(registers, "cr3"));
1087 register_state.Cr4 = (UINT32)json_object_get_uint64(
1088 json_object_object_get(registers, "cr4"));
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001089
Lawrence Tange407b4c2022-07-21 13:54:01 +01001090 //64-bit registers are split into two 32-bit parts.
1091 UINT64 gdtr = json_object_get_uint64(
1092 json_object_object_get(registers, "gdtr"));
1093 register_state.Gdtr[0] = gdtr & 0xFFFFFFFF;
1094 register_state.Gdtr[1] = gdtr >> 32;
1095 UINT64 idtr = json_object_get_uint64(
1096 json_object_object_get(registers, "idtr"));
1097 register_state.Idtr[0] = idtr & 0xFFFFFFFF;
1098 register_state.Idtr[1] = idtr >> 32;
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001099
Lawrence Tange407b4c2022-07-21 13:54:01 +01001100 //16-bit registers.
1101 register_state.Ldtr = (UINT16)json_object_get_uint64(
1102 json_object_object_get(registers, "ldtr"));
1103 register_state.Tr = (UINT16)json_object_get_uint64(
1104 json_object_object_get(registers, "tr"));
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001105
Lawrence Tange407b4c2022-07-21 13:54:01 +01001106 //Write out to stream.
1107 fwrite(&register_state, sizeof(EFI_CONTEXT_IA32_REGISTER_STATE), 1,
1108 out);
1109 fflush(out);
Lawrence Tangd0c88842022-07-13 14:51:17 +01001110}
1111
1112//Converts a single CPER-JSON x64 register array into CPER binary, outputting to the given stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +01001113void ir_ia32x64_x64_registers_to_cper(json_object *registers, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +01001114{
Lawrence Tange407b4c2022-07-21 13:54:01 +01001115 EFI_CONTEXT_X64_REGISTER_STATE register_state;
1116 register_state.Rax = json_object_get_uint64(
1117 json_object_object_get(registers, "rax"));
1118 register_state.Rbx = json_object_get_uint64(
1119 json_object_object_get(registers, "rbx"));
1120 register_state.Rcx = json_object_get_uint64(
1121 json_object_object_get(registers, "rcx"));
1122 register_state.Rdx = json_object_get_uint64(
1123 json_object_object_get(registers, "rdx"));
1124 register_state.Rsi = json_object_get_uint64(
1125 json_object_object_get(registers, "rsi"));
1126 register_state.Rdi = json_object_get_uint64(
1127 json_object_object_get(registers, "rdi"));
1128 register_state.Rbp = json_object_get_uint64(
1129 json_object_object_get(registers, "rbp"));
1130 register_state.Rsp = json_object_get_uint64(
1131 json_object_object_get(registers, "rsp"));
1132 register_state.R8 =
1133 json_object_get_uint64(json_object_object_get(registers, "r8"));
1134 register_state.R9 =
1135 json_object_get_uint64(json_object_object_get(registers, "r9"));
1136 register_state.R10 = json_object_get_uint64(
1137 json_object_object_get(registers, "r10"));
1138 register_state.R11 = json_object_get_uint64(
1139 json_object_object_get(registers, "r11"));
1140 register_state.R12 = json_object_get_uint64(
1141 json_object_object_get(registers, "r12"));
1142 register_state.R13 = json_object_get_uint64(
1143 json_object_object_get(registers, "r13"));
1144 register_state.R14 = json_object_get_uint64(
1145 json_object_object_get(registers, "r14"));
1146 register_state.R15 = json_object_get_uint64(
1147 json_object_object_get(registers, "r15"));
1148 register_state.Cs = (UINT16)json_object_get_int(
1149 json_object_object_get(registers, "cs"));
1150 register_state.Ds = (UINT16)json_object_get_int(
1151 json_object_object_get(registers, "ds"));
1152 register_state.Ss = (UINT16)json_object_get_int(
1153 json_object_object_get(registers, "ss"));
1154 register_state.Es = (UINT16)json_object_get_int(
1155 json_object_object_get(registers, "es"));
1156 register_state.Fs = (UINT16)json_object_get_int(
1157 json_object_object_get(registers, "fs"));
1158 register_state.Gs = (UINT16)json_object_get_int(
1159 json_object_object_get(registers, "gs"));
1160 register_state.Resv1 = 0;
1161 register_state.Rflags = json_object_get_uint64(
1162 json_object_object_get(registers, "rflags"));
1163 register_state.Rip = json_object_get_uint64(
1164 json_object_object_get(registers, "eip"));
1165 register_state.Cr0 = json_object_get_uint64(
1166 json_object_object_get(registers, "cr0"));
1167 register_state.Cr1 = json_object_get_uint64(
1168 json_object_object_get(registers, "cr1"));
1169 register_state.Cr2 = json_object_get_uint64(
1170 json_object_object_get(registers, "cr2"));
1171 register_state.Cr3 = json_object_get_uint64(
1172 json_object_object_get(registers, "cr3"));
1173 register_state.Cr4 = json_object_get_uint64(
1174 json_object_object_get(registers, "cr4"));
1175 register_state.Cr8 = json_object_get_uint64(
1176 json_object_object_get(registers, "cr8"));
1177 register_state.Gdtr[0] = json_object_get_uint64(
1178 json_object_object_get(registers, "gdtr_0"));
1179 register_state.Gdtr[1] = json_object_get_uint64(
1180 json_object_object_get(registers, "gdtr_1"));
1181 register_state.Idtr[0] = json_object_get_uint64(
1182 json_object_object_get(registers, "idtr_0"));
1183 register_state.Idtr[1] = json_object_get_uint64(
1184 json_object_object_get(registers, "idtr_1"));
1185 register_state.Ldtr = (UINT16)json_object_get_int(
1186 json_object_object_get(registers, "ldtr"));
1187 register_state.Tr = (UINT16)json_object_get_int(
1188 json_object_object_get(registers, "tr"));
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001189
Lawrence Tange407b4c2022-07-21 13:54:01 +01001190 //Write out to stream.
1191 fwrite(&register_state, sizeof(EFI_CONTEXT_X64_REGISTER_STATE), 1, out);
1192 fflush(out);
John Chungf8fc7052024-05-03 20:05:29 +08001193}