blob: 85f03a47726af22a14a548b514e13a20a4a43943 [file] [log] [blame]
Lawrence Tang794312c2022-07-05 14:46:10 +01001/**
2 * Describes functions for converting IA32/x64 CPER sections from binary and JSON format
3 * into an intermediate format.
Ed Tanousfedd4572024-07-12 13:56:00 -07004 *
Lawrence Tang794312c2022-07-05 14:46:10 +01005 * Author: Lawrence.Tang@arm.com
6 **/
7
8#include <stdio.h>
Lawrence Tang5202bbb2022-08-12 14:54:36 +01009#include <json.h>
Thu Nguyene42fb482024-10-15 14:43:11 +000010#include <libcper/base64.h>
11#include <libcper/Cper.h>
12#include <libcper/cper-utils.h>
13#include <libcper/sections/cper-section-ia32x64.h>
Ed Tanous50b966f2025-03-11 09:06:19 -070014#include <libcper/log.h>
Lawrence Tang794312c2022-07-05 14:46:10 +010015
16//Private pre-definitions.
Lawrence Tange407b4c2022-07-21 13:54:01 +010017json_object *cper_ia32x64_processor_error_info_to_ir(
18 EFI_IA32_X64_PROCESS_ERROR_INFO *error_info);
19json_object *cper_ia32x64_cache_tlb_check_to_ir(
20 EFI_IA32_X64_CACHE_CHECK_INFO *cache_tlb_check);
21json_object *
22cper_ia32x64_bus_check_to_ir(EFI_IA32_X64_BUS_CHECK_INFO *bus_check);
23json_object *cper_ia32x64_ms_check_to_ir(EFI_IA32_X64_MS_CHECK_INFO *ms_check);
24json_object *cper_ia32x64_processor_context_info_to_ir(
Ed Tanous12dbd4f2025-03-08 19:05:01 -080025 EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *context_info, void **cur_pos,
26 UINT32 *remaining_size);
Lawrence Tange407b4c2022-07-21 13:54:01 +010027json_object *
28cper_ia32x64_register_32bit_to_ir(EFI_CONTEXT_IA32_REGISTER_STATE *registers);
29json_object *
30cper_ia32x64_register_64bit_to_ir(EFI_CONTEXT_X64_REGISTER_STATE *registers);
31void ir_ia32x64_error_info_to_cper(json_object *error_info, FILE *out);
32void ir_ia32x64_context_info_to_cper(json_object *context_info, FILE *out);
33void ir_ia32x64_cache_tlb_check_error_to_cper(
34 json_object *check_info,
35 EFI_IA32_X64_CACHE_CHECK_INFO *check_info_cper);
36void ir_ia32x64_bus_check_error_to_cper(
37 json_object *check_info, EFI_IA32_X64_BUS_CHECK_INFO *check_info_cper);
38void ir_ia32x64_ms_check_error_to_cper(
39 json_object *check_info, EFI_IA32_X64_MS_CHECK_INFO *check_info_cper);
40void ir_ia32x64_ia32_registers_to_cper(json_object *registers, FILE *out);
41void ir_ia32x64_x64_registers_to_cper(json_object *registers, FILE *out);
Lawrence Tangd0c88842022-07-13 14:51:17 +010042
43//////////////////
44/// CPER TO IR ///
45//////////////////
Lawrence Tang794312c2022-07-05 14:46:10 +010046
47//Converts the IA32/x64 error section described in the given descriptor into intermediate format.
Ed Tanous12dbd4f2025-03-08 19:05:01 -080048json_object *cper_section_ia32x64_to_ir(const UINT8 *section, UINT32 size)
Lawrence Tang794312c2022-07-05 14:46:10 +010049{
Ed Tanous12dbd4f2025-03-08 19:05:01 -080050 if (size < sizeof(EFI_IA32_X64_PROCESSOR_ERROR_RECORD)) {
51 return NULL;
52 }
Lawrence Tange407b4c2022-07-21 13:54:01 +010053 EFI_IA32_X64_PROCESSOR_ERROR_RECORD *record =
54 (EFI_IA32_X64_PROCESSOR_ERROR_RECORD *)section;
Ed Tanous12dbd4f2025-03-08 19:05:01 -080055 UINT32 remaining_size =
56 size - sizeof(EFI_IA32_X64_PROCESSOR_ERROR_RECORD);
Lawrence Tange407b4c2022-07-21 13:54:01 +010057 json_object *record_ir = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +010058
Lawrence Tange407b4c2022-07-21 13:54:01 +010059 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080060 //validation bits contain information
61 //about processorErrorInfoNum and processorContextInfoNum.
62 //Ensure this is decoded properly in IR->CPER
John Chungf8fc7052024-05-03 20:05:29 +080063 int processor_error_info_num = (record->ValidFields >> 2) & 0x3F;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080064 json_object_object_add(record_ir, "processorErrorInfoNum",
Lawrence Tange407b4c2022-07-21 13:54:01 +010065 json_object_new_int(processor_error_info_num));
John Chungf8fc7052024-05-03 20:05:29 +080066 int processor_context_info_num = (record->ValidFields >> 8) & 0x3F;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080067 json_object_object_add(record_ir, "processorContextInfoNum",
Lawrence Tange407b4c2022-07-21 13:54:01 +010068 json_object_new_int(processor_context_info_num));
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080069
70 ValidationTypes ui64Type = { UINT_64T,
71 .value.ui64 = record->ValidFields };
Lawrence Tang794312c2022-07-05 14:46:10 +010072
Lawrence Tange407b4c2022-07-21 13:54:01 +010073 //APIC ID.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080074 if (isvalid_prop_to_ir(&ui64Type, 0)) {
75 json_object_object_add(record_ir, "localAPICID",
76 json_object_new_uint64(record->ApicId));
77 }
Lawrence Tang794312c2022-07-05 14:46:10 +010078
Lawrence Tange407b4c2022-07-21 13:54:01 +010079 //CPUID information.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080080 if (isvalid_prop_to_ir(&ui64Type, 1)) {
81 json_object *cpuid_info_ir = json_object_new_object();
82 EFI_IA32_X64_CPU_ID *cpuid_info =
83 (EFI_IA32_X64_CPU_ID *)record->CpuIdInfo;
84 json_object_object_add(cpuid_info_ir, "eax",
85 json_object_new_uint64(cpuid_info->Eax));
86 json_object_object_add(cpuid_info_ir, "ebx",
87 json_object_new_uint64(cpuid_info->Ebx));
88 json_object_object_add(cpuid_info_ir, "ecx",
89 json_object_new_uint64(cpuid_info->Ecx));
90 json_object_object_add(cpuid_info_ir, "edx",
91 json_object_new_uint64(cpuid_info->Edx));
92 json_object_object_add(record_ir, "cpuidInfo", cpuid_info_ir);
93 }
Lawrence Tang794312c2022-07-05 14:46:10 +010094
Lawrence Tange407b4c2022-07-21 13:54:01 +010095 //Processor error information, of the amount described above.
96 EFI_IA32_X64_PROCESS_ERROR_INFO *current_error_info =
97 (EFI_IA32_X64_PROCESS_ERROR_INFO *)(record + 1);
98 json_object *error_info_array = json_object_new_array();
Ed Tanous12dbd4f2025-03-08 19:05:01 -080099 if (remaining_size < (processor_error_info_num *
100 sizeof(EFI_IA32_X64_PROCESS_ERROR_INFO))) {
101 json_object_put(error_info_array);
102 json_object_put(record_ir);
Ed Tanous50b966f2025-03-11 09:06:19 -0700103 cper_print_log(
104 "Invalid CPER file: Invalid processor error info num.\n");
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800105 return NULL;
106 }
107
Lawrence Tange407b4c2022-07-21 13:54:01 +0100108 for (int i = 0; i < processor_error_info_num; i++) {
109 json_object_array_add(error_info_array,
110 cper_ia32x64_processor_error_info_to_ir(
111 current_error_info));
112 current_error_info++;
113 }
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800114 remaining_size -= processor_error_info_num *
115 sizeof(EFI_IA32_X64_PROCESS_ERROR_INFO);
116
Lawrence Tange407b4c2022-07-21 13:54:01 +0100117 json_object_object_add(record_ir, "processorErrorInfo",
118 error_info_array);
Lawrence Tang794312c2022-07-05 14:46:10 +0100119
Lawrence Tange407b4c2022-07-21 13:54:01 +0100120 //Processor context information, of the amount described above.
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800121 if (remaining_size < (processor_context_info_num *
122 sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO))) {
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800123 json_object_put(record_ir);
Ed Tanous50b966f2025-03-11 09:06:19 -0700124 cper_print_log(
125 "Invalid CPER file: Invalid processor context info num.\n");
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800126 return NULL;
127 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100128 EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *current_context_info =
129 (EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *)current_error_info;
130 void *cur_pos = (void *)current_context_info;
131 json_object *context_info_array = json_object_new_array();
132 for (int i = 0; i < processor_context_info_num; i++) {
Ed Tanousd6b62632025-03-14 15:30:07 -0700133 json_object *context_info =
134 cper_ia32x64_processor_context_info_to_ir(
135 current_context_info, &cur_pos,
136 &remaining_size);
Ed Tanousd6b62632025-03-14 15:30:07 -0700137 json_object_array_add(context_info_array, context_info);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100138 current_context_info =
139 (EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *)cur_pos;
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800140
Lawrence Tange407b4c2022-07-21 13:54:01 +0100141 //The context array is a non-fixed size, pointer is shifted within the above function.
142 }
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800143
Lawrence Tange407b4c2022-07-21 13:54:01 +0100144 json_object_object_add(record_ir, "processorContextInfo",
145 context_info_array);
Lawrence Tang794312c2022-07-05 14:46:10 +0100146
Lawrence Tange407b4c2022-07-21 13:54:01 +0100147 return record_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100148}
149
Ed Tanous1a648562025-03-10 15:23:38 -0700150EFI_GUID *gEfiIa32x64ErrorTypeGuids[] = {
151 &gEfiIa32x64ErrorTypeCacheCheckGuid,
152 &gEfiIa32x64ErrorTypeTlbCheckGuid,
153 &gEfiIa32x64ErrorTypeBusCheckGuid,
154 &gEfiIa32x64ErrorTypeMsCheckGuid,
155};
156
Lawrence Tang794312c2022-07-05 14:46:10 +0100157//Converts a single IA32/x64 processor error info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100158json_object *cper_ia32x64_processor_error_info_to_ir(
159 EFI_IA32_X64_PROCESS_ERROR_INFO *error_info)
Lawrence Tang794312c2022-07-05 14:46:10 +0100160{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100161 json_object *error_info_ir = json_object_new_object();
Ed Tanousc2ebddd2025-03-09 10:07:01 -0700162 json_object *type = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +0100163
Lawrence Tange407b4c2022-07-21 13:54:01 +0100164 //Error structure type (as GUID).
Ed Tanousc2ebddd2025-03-09 10:07:01 -0700165 add_guid(type, "guid", &error_info->ErrorType);
Lawrence Tang794312c2022-07-05 14:46:10 +0100166
Lawrence Tang3592da72022-07-21 16:50:07 +0100167 //Get the error structure type as a readable string.
168 const char *readable_type = "Unknown";
Ed Tanous1a648562025-03-10 15:23:38 -0700169
170 const char *readable_names[] = {
171 "Cache Check Error",
172 "TLB Check Error",
173 "Bus Check Error",
174 "MS Check Error",
175 };
176
177 int index = select_guid_from_list(
178 &error_info->ErrorType, gEfiIa32x64ErrorTypeGuids,
179 sizeof(gEfiIa32x64ErrorTypeGuids) / sizeof(EFI_GUID *));
180
181 if (index < (int)(sizeof(readable_names) / sizeof(char *))) {
182 readable_type = readable_names[index];
John Chungf8fc7052024-05-03 20:05:29 +0800183 }
Ed Tanous1a648562025-03-10 15:23:38 -0700184
John Chungf8fc7052024-05-03 20:05:29 +0800185 json_object_object_add(type, "name",
186 json_object_new_string(readable_type));
Lawrence Tang3592da72022-07-21 16:50:07 +0100187 json_object_object_add(error_info_ir, "type", type);
188
Lawrence Tange407b4c2022-07-21 13:54:01 +0100189 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800190 ValidationTypes ui64Type = { UINT_64T,
191 .value.ui64 = error_info->ValidFields };
Lawrence Tang794312c2022-07-05 14:46:10 +0100192
Lawrence Tange407b4c2022-07-21 13:54:01 +0100193 //Add the check information on a per-structure basis.
194 //Cache and TLB check information are identical, so can be equated.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800195 if (isvalid_prop_to_ir(&ui64Type, 0)) {
196 json_object *check_information = NULL;
Ed Tanous1a648562025-03-10 15:23:38 -0700197
198 switch (index) {
199 case 0:
200 case 1:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800201 check_information = cper_ia32x64_cache_tlb_check_to_ir(
202 (EFI_IA32_X64_CACHE_CHECK_INFO *)&error_info
203 ->CheckInfo);
Ed Tanous1a648562025-03-10 15:23:38 -0700204 break;
205 case 2:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800206 check_information = cper_ia32x64_bus_check_to_ir(
207 (EFI_IA32_X64_BUS_CHECK_INFO *)&error_info
208 ->CheckInfo);
Ed Tanous1a648562025-03-10 15:23:38 -0700209 break;
210 case 3:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800211 check_information = cper_ia32x64_ms_check_to_ir(
212 (EFI_IA32_X64_MS_CHECK_INFO *)&error_info
213 ->CheckInfo);
Ed Tanous1a648562025-03-10 15:23:38 -0700214 break;
215 default:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800216 //Unknown check information.
Ed Tanous50b966f2025-03-11 09:06:19 -0700217 cper_print_log(
218 "WARN: Invalid/unknown check information GUID found in IA32/x64 CPER section. Ignoring.\n");
Ed Tanous1a648562025-03-10 15:23:38 -0700219 break;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800220 }
Ed Tanous8e423942025-03-14 23:11:06 -0700221 if (check_information != NULL) {
222 json_object_object_add(error_info_ir, "checkInfo",
223 check_information);
224 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100225 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100226
Lawrence Tange407b4c2022-07-21 13:54:01 +0100227 //Target, requestor, and responder identifiers.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800228 if (isvalid_prop_to_ir(&ui64Type, 1)) {
229 json_object_object_add(
230 error_info_ir, "targetAddressID",
231 json_object_new_uint64(error_info->TargetId));
232 }
233 if (isvalid_prop_to_ir(&ui64Type, 2)) {
234 json_object_object_add(
235 error_info_ir, "requestorID",
236 json_object_new_uint64(error_info->RequestorId));
237 }
238 if (isvalid_prop_to_ir(&ui64Type, 3)) {
239 json_object_object_add(
240 error_info_ir, "responderID",
241 json_object_new_uint64(error_info->ResponderId));
242 }
243 if (isvalid_prop_to_ir(&ui64Type, 4)) {
244 json_object_object_add(
245 error_info_ir, "instructionPointer",
246 json_object_new_uint64(error_info->InstructionIP));
247 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100248
Lawrence Tange407b4c2022-07-21 13:54:01 +0100249 return error_info_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100250}
251
252//Converts a single IA32/x64 cache or TLB check check info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100253json_object *cper_ia32x64_cache_tlb_check_to_ir(
254 EFI_IA32_X64_CACHE_CHECK_INFO *cache_tlb_check)
Lawrence Tang794312c2022-07-05 14:46:10 +0100255{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100256 json_object *cache_tlb_check_ir = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +0100257
Lawrence Tange407b4c2022-07-21 13:54:01 +0100258 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800259 ValidationTypes ui64Type = {
260 UINT_64T, .value.ui64 = cache_tlb_check->ValidFields
261 };
Lawrence Tang794312c2022-07-05 14:46:10 +0100262
Lawrence Tange407b4c2022-07-21 13:54:01 +0100263 //Transaction type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800264 if (isvalid_prop_to_ir(&ui64Type, 0)) {
265 json_object *transaction_type = integer_to_readable_pair(
266 cache_tlb_check->TransactionType, 3,
267 IA32X64_CHECK_INFO_TRANSACTION_TYPES_KEYS,
268 IA32X64_CHECK_INFO_TRANSACTION_TYPES_VALUES,
269 "Unknown (Reserved)");
270 json_object_object_add(cache_tlb_check_ir, "transactionType",
271 transaction_type);
272 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100273
Lawrence Tange407b4c2022-07-21 13:54:01 +0100274 //Operation.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800275 if (isvalid_prop_to_ir(&ui64Type, 1)) {
276 json_object *operation = integer_to_readable_pair(
277 cache_tlb_check->Operation, 9,
278 IA32X64_CHECK_INFO_OPERATION_TYPES_KEYS,
279 IA32X64_CHECK_INFO_OPERATION_TYPES_VALUES,
280 "Unknown (Reserved)");
281 json_object_object_add(cache_tlb_check_ir, "operation",
282 operation);
283 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100284
Lawrence Tange407b4c2022-07-21 13:54:01 +0100285 //Affected cache/TLB level.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800286 if (isvalid_prop_to_ir(&ui64Type, 2)) {
287 json_object_object_add(
288 cache_tlb_check_ir, "level",
289 json_object_new_uint64(cache_tlb_check->Level));
290 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100291
Lawrence Tange407b4c2022-07-21 13:54:01 +0100292 //Miscellaneous boolean fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800293 if (isvalid_prop_to_ir(&ui64Type, 3)) {
294 json_object_object_add(
295 cache_tlb_check_ir, "processorContextCorrupt",
296 json_object_new_boolean(
297 cache_tlb_check->ContextCorrupt));
298 }
299 if (isvalid_prop_to_ir(&ui64Type, 4)) {
300 json_object_object_add(
301 cache_tlb_check_ir, "uncorrected",
302 json_object_new_boolean(
303 cache_tlb_check->ErrorUncorrected));
304 }
305 if (isvalid_prop_to_ir(&ui64Type, 5)) {
306 json_object_object_add(
307 cache_tlb_check_ir, "preciseIP",
308 json_object_new_boolean(cache_tlb_check->PreciseIp));
309 }
310 if (isvalid_prop_to_ir(&ui64Type, 6)) {
311 json_object_object_add(cache_tlb_check_ir, "restartableIP",
312 json_object_new_boolean(
313 cache_tlb_check->RestartableIp));
314 }
315 if (isvalid_prop_to_ir(&ui64Type, 7)) {
316 json_object_object_add(
317 cache_tlb_check_ir, "overflow",
318 json_object_new_boolean(cache_tlb_check->Overflow));
319 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100320
Lawrence Tange407b4c2022-07-21 13:54:01 +0100321 return cache_tlb_check_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100322}
323
324//Converts a single IA32/x64 bus check check info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100325json_object *
326cper_ia32x64_bus_check_to_ir(EFI_IA32_X64_BUS_CHECK_INFO *bus_check)
327{
328 json_object *bus_check_ir = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +0100329
Lawrence Tange407b4c2022-07-21 13:54:01 +0100330 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800331 ValidationTypes ui64Type = { UINT_64T,
332 .value.ui64 = bus_check->ValidFields };
Lawrence Tang794312c2022-07-05 14:46:10 +0100333
Lawrence Tange407b4c2022-07-21 13:54:01 +0100334 //Transaction type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800335 if (isvalid_prop_to_ir(&ui64Type, 0)) {
336 json_object *transaction_type = integer_to_readable_pair(
337 bus_check->TransactionType, 3,
338 IA32X64_CHECK_INFO_TRANSACTION_TYPES_KEYS,
339 IA32X64_CHECK_INFO_TRANSACTION_TYPES_VALUES,
340 "Unknown (Reserved)");
341 json_object_object_add(bus_check_ir, "transactionType",
342 transaction_type);
343 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100344
Lawrence Tange407b4c2022-07-21 13:54:01 +0100345 //Operation.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800346 if (isvalid_prop_to_ir(&ui64Type, 1)) {
347 json_object *operation = integer_to_readable_pair(
348 bus_check->Operation, 9,
349 IA32X64_CHECK_INFO_OPERATION_TYPES_KEYS,
350 IA32X64_CHECK_INFO_OPERATION_TYPES_VALUES,
351 "Unknown (Reserved)");
352 json_object_object_add(bus_check_ir, "operation", operation);
353 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100354
Lawrence Tange407b4c2022-07-21 13:54:01 +0100355 //Affected bus level.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800356 if (isvalid_prop_to_ir(&ui64Type, 2)) {
357 json_object_object_add(
358 bus_check_ir, "level",
359 json_object_new_uint64(bus_check->Level));
360 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100361
Lawrence Tange407b4c2022-07-21 13:54:01 +0100362 //Miscellaneous boolean fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800363 if (isvalid_prop_to_ir(&ui64Type, 3)) {
364 json_object_object_add(
365 bus_check_ir, "processorContextCorrupt",
366 json_object_new_boolean(bus_check->ContextCorrupt));
367 }
368 if (isvalid_prop_to_ir(&ui64Type, 4)) {
369 json_object_object_add(
370 bus_check_ir, "uncorrected",
371 json_object_new_boolean(bus_check->ErrorUncorrected));
372 }
373 if (isvalid_prop_to_ir(&ui64Type, 5)) {
374 json_object_object_add(
375 bus_check_ir, "preciseIP",
376 json_object_new_boolean(bus_check->PreciseIp));
377 }
378 if (isvalid_prop_to_ir(&ui64Type, 6)) {
379 json_object_object_add(
380 bus_check_ir, "restartableIP",
381 json_object_new_boolean(bus_check->RestartableIp));
382 }
383 if (isvalid_prop_to_ir(&ui64Type, 7)) {
384 json_object_object_add(
385 bus_check_ir, "overflow",
386 json_object_new_boolean(bus_check->Overflow));
387 }
388 if (isvalid_prop_to_ir(&ui64Type, 9)) {
389 json_object_object_add(
390 bus_check_ir, "timedOut",
391 json_object_new_boolean(bus_check->TimeOut));
392 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100393
Lawrence Tange407b4c2022-07-21 13:54:01 +0100394 //Participation type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800395 if (isvalid_prop_to_ir(&ui64Type, 8)) {
396 json_object *participation_type = integer_to_readable_pair(
397 bus_check->ParticipationType, 4,
398 IA32X64_BUS_CHECK_INFO_PARTICIPATION_TYPES_KEYS,
399 IA32X64_BUS_CHECK_INFO_PARTICIPATION_TYPES_VALUES,
400 "Unknown");
401 json_object_object_add(bus_check_ir, "participationType",
402 participation_type);
403 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100404
Lawrence Tange407b4c2022-07-21 13:54:01 +0100405 //Address space.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800406 if (isvalid_prop_to_ir(&ui64Type, 10)) {
407 json_object *address_space = integer_to_readable_pair(
408 bus_check->AddressSpace, 4,
409 IA32X64_BUS_CHECK_INFO_ADDRESS_SPACE_TYPES_KEYS,
410 IA32X64_BUS_CHECK_INFO_ADDRESS_SPACE_TYPES_VALUES,
411 "Unknown");
412 json_object_object_add(bus_check_ir, "addressSpace",
413 address_space);
414 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100415
416 return bus_check_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100417}
418
419//Converts a single IA32/x64 MS check check info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100420json_object *cper_ia32x64_ms_check_to_ir(EFI_IA32_X64_MS_CHECK_INFO *ms_check)
Lawrence Tang794312c2022-07-05 14:46:10 +0100421{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100422 json_object *ms_check_ir = json_object_new_object();
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800423 ValidationTypes ui64Type = { UINT_64T,
424 .value.ui64 = ms_check->ValidFields };
Lawrence Tange407b4c2022-07-21 13:54:01 +0100425 //Validation bits.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100426 //Error type (operation that caused the error).
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800427 if (isvalid_prop_to_ir(&ui64Type, 0)) {
428 json_object *error_type = integer_to_readable_pair(
429 ms_check->ErrorType, 4,
430 IA32X64_MS_CHECK_INFO_ERROR_TYPES_KEYS,
431 IA32X64_MS_CHECK_INFO_ERROR_TYPES_VALUES,
432 "Unknown (Processor Specific)");
433 json_object_object_add(ms_check_ir, "errorType", error_type);
434 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100435
Lawrence Tange407b4c2022-07-21 13:54:01 +0100436 //Miscellaneous fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800437 if (isvalid_prop_to_ir(&ui64Type, 1)) {
438 json_object_object_add(
439 ms_check_ir, "processorContextCorrupt",
440 json_object_new_boolean(ms_check->ContextCorrupt));
441 }
442 if (isvalid_prop_to_ir(&ui64Type, 2)) {
443 json_object_object_add(
444 ms_check_ir, "uncorrected",
445 json_object_new_boolean(ms_check->ErrorUncorrected));
446 }
447 if (isvalid_prop_to_ir(&ui64Type, 3)) {
448 json_object_object_add(
449 ms_check_ir, "preciseIP",
450 json_object_new_boolean(ms_check->PreciseIp));
451 }
452 if (isvalid_prop_to_ir(&ui64Type, 4)) {
453 json_object_object_add(
454 ms_check_ir, "restartableIP",
455 json_object_new_boolean(ms_check->RestartableIp));
456 }
457 if (isvalid_prop_to_ir(&ui64Type, 5)) {
458 json_object_object_add(
459 ms_check_ir, "overflow",
460 json_object_new_boolean(ms_check->Overflow));
461 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100462
463 return ms_check_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100464}
465
466//Converts a single IA32/x64 processor context info entry into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100467json_object *cper_ia32x64_processor_context_info_to_ir(
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800468 EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *context_info, void **cur_pos,
469 UINT32 *remaining_size)
Lawrence Tang794312c2022-07-05 14:46:10 +0100470{
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800471 if (*remaining_size < sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO)) {
Ed Tanous8e423942025-03-14 23:11:06 -0700472 return NULL;
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800473 }
474 *remaining_size -= sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO);
Ed Tanous8e423942025-03-14 23:11:06 -0700475 json_object *context_info_ir = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +0100476
Lawrence Tange407b4c2022-07-21 13:54:01 +0100477 //Register context type.
478 json_object *context_type = integer_to_readable_pair(
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800479 context_info->RegisterType, IA32X64_REGISTER_CONTEXT_TYPES_SIZE,
Lawrence Tange407b4c2022-07-21 13:54:01 +0100480 IA32X64_REGISTER_CONTEXT_TYPES_KEYS,
481 IA32X64_REGISTER_CONTEXT_TYPES_VALUES, "Unknown (Reserved)");
482 json_object_object_add(context_info_ir, "registerContextType",
483 context_type);
Lawrence Tang794312c2022-07-05 14:46:10 +0100484
Lawrence Tange407b4c2022-07-21 13:54:01 +0100485 //Register array size, MSR and MM address.
486 json_object_object_add(context_info_ir, "registerArraySize",
487 json_object_new_uint64(context_info->ArraySize));
488 json_object_object_add(
489 context_info_ir, "msrAddress",
490 json_object_new_uint64(context_info->MsrAddress));
491 json_object_object_add(
492 context_info_ir, "mmRegisterAddress",
493 json_object_new_uint64(context_info->MmRegisterAddress));
Lawrence Tang794312c2022-07-05 14:46:10 +0100494
Lawrence Tange407b4c2022-07-21 13:54:01 +0100495 //Register array.
496 json_object *register_array = NULL;
497 if (context_info->RegisterType == EFI_REG_CONTEXT_TYPE_IA32) {
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800498 if (*remaining_size < sizeof(EFI_CONTEXT_IA32_REGISTER_STATE)) {
Ed Tanousd6b62632025-03-14 15:30:07 -0700499 return context_info_ir;
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800500 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100501 EFI_CONTEXT_IA32_REGISTER_STATE *register_state =
502 (EFI_CONTEXT_IA32_REGISTER_STATE *)(context_info + 1);
503 register_array =
504 cper_ia32x64_register_32bit_to_ir(register_state);
505 *cur_pos = (void *)(register_state + 1);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800506 *remaining_size -= sizeof(EFI_CONTEXT_IA32_REGISTER_STATE);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100507 } else if (context_info->RegisterType == EFI_REG_CONTEXT_TYPE_X64) {
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800508 if (*remaining_size < sizeof(EFI_CONTEXT_X64_REGISTER_STATE)) {
Ed Tanousd6b62632025-03-14 15:30:07 -0700509 return context_info_ir;
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800510 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100511 EFI_CONTEXT_X64_REGISTER_STATE *register_state =
512 (EFI_CONTEXT_X64_REGISTER_STATE *)(context_info + 1);
513 register_array =
514 cper_ia32x64_register_64bit_to_ir(register_state);
515 *cur_pos = (void *)(register_state + 1);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800516 *remaining_size -= sizeof(EFI_CONTEXT_X64_REGISTER_STATE);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100517 } else {
518 //No parseable data, just dump as base64 and shift the head to the next item.
519 *cur_pos = (void *)(context_info + 1);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800520 if (*remaining_size < context_info->ArraySize) {
Ed Tanousd6b62632025-03-14 15:30:07 -0700521 return context_info_ir;
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800522 }
Ed Tanousa7d2cdd2024-07-15 11:07:27 -0700523 int32_t encoded_len = 0;
524 char *encoded = base64_encode((UINT8 *)*cur_pos,
525 context_info->ArraySize,
526 &encoded_len);
527 if (encoded == NULL) {
Ed Tanous50b966f2025-03-11 09:06:19 -0700528 cper_print_log(
529 "Failed to allocate encode output buffer. \n");
John Chungf8fc7052024-05-03 20:05:29 +0800530 } else {
John Chungf8fc7052024-05-03 20:05:29 +0800531 register_array = json_object_new_object();
532 json_object_object_add(register_array, "data",
533 json_object_new_string_len(
534 encoded, encoded_len));
535 free(encoded);
536 }
Lawrence Tangd7e8ca32022-07-07 10:25:53 +0100537
Lawrence Tange407b4c2022-07-21 13:54:01 +0100538 *cur_pos =
539 (void *)(((char *)*cur_pos) + context_info->ArraySize);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800540 *remaining_size -= context_info->ArraySize;
Lawrence Tange407b4c2022-07-21 13:54:01 +0100541 }
Ed Tanous8e423942025-03-14 23:11:06 -0700542 if (register_array != NULL) {
543 json_object_object_add(context_info_ir, "registerArray",
544 register_array);
545 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100546
Lawrence Tange407b4c2022-07-21 13:54:01 +0100547 return context_info_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100548}
549
550//Converts a single CPER IA32 register state into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100551json_object *
552cper_ia32x64_register_32bit_to_ir(EFI_CONTEXT_IA32_REGISTER_STATE *registers)
Lawrence Tang794312c2022-07-05 14:46:10 +0100553{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100554 json_object *ia32_registers = json_object_new_object();
555 json_object_object_add(ia32_registers, "eax",
556 json_object_new_uint64(registers->Eax));
557 json_object_object_add(ia32_registers, "ebx",
558 json_object_new_uint64(registers->Ebx));
559 json_object_object_add(ia32_registers, "ecx",
560 json_object_new_uint64(registers->Ecx));
561 json_object_object_add(ia32_registers, "edx",
562 json_object_new_uint64(registers->Edx));
563 json_object_object_add(ia32_registers, "esi",
564 json_object_new_uint64(registers->Esi));
565 json_object_object_add(ia32_registers, "edi",
566 json_object_new_uint64(registers->Edi));
567 json_object_object_add(ia32_registers, "ebp",
568 json_object_new_uint64(registers->Ebp));
569 json_object_object_add(ia32_registers, "esp",
570 json_object_new_uint64(registers->Esp));
571 json_object_object_add(ia32_registers, "cs",
572 json_object_new_uint64(registers->Cs));
573 json_object_object_add(ia32_registers, "ds",
574 json_object_new_uint64(registers->Ds));
575 json_object_object_add(ia32_registers, "ss",
576 json_object_new_uint64(registers->Ss));
577 json_object_object_add(ia32_registers, "es",
578 json_object_new_uint64(registers->Es));
579 json_object_object_add(ia32_registers, "fs",
580 json_object_new_uint64(registers->Fs));
581 json_object_object_add(ia32_registers, "gs",
582 json_object_new_uint64(registers->Gs));
583 json_object_object_add(ia32_registers, "eflags",
584 json_object_new_uint64(registers->Eflags));
585 json_object_object_add(ia32_registers, "eip",
586 json_object_new_uint64(registers->Eip));
587 json_object_object_add(ia32_registers, "cr0",
588 json_object_new_uint64(registers->Cr0));
589 json_object_object_add(ia32_registers, "cr1",
590 json_object_new_uint64(registers->Cr1));
591 json_object_object_add(ia32_registers, "cr2",
592 json_object_new_uint64(registers->Cr2));
593 json_object_object_add(ia32_registers, "cr3",
594 json_object_new_uint64(registers->Cr3));
595 json_object_object_add(ia32_registers, "cr4",
596 json_object_new_uint64(registers->Cr4));
597 json_object_object_add(
598 ia32_registers, "gdtr",
599 json_object_new_uint64(registers->Gdtr[0] +
600 ((UINT64)registers->Gdtr[1] << 32)));
601 json_object_object_add(
602 ia32_registers, "idtr",
603 json_object_new_uint64(registers->Idtr[0] +
604 ((UINT64)registers->Idtr[1] << 32)));
605 json_object_object_add(ia32_registers, "ldtr",
606 json_object_new_uint64(registers->Ldtr));
607 json_object_object_add(ia32_registers, "tr",
608 json_object_new_uint64(registers->Tr));
Lawrence Tang794312c2022-07-05 14:46:10 +0100609
Lawrence Tange407b4c2022-07-21 13:54:01 +0100610 return ia32_registers;
Lawrence Tang794312c2022-07-05 14:46:10 +0100611}
612
613//Converts a single CPER x64 register state into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100614json_object *
615cper_ia32x64_register_64bit_to_ir(EFI_CONTEXT_X64_REGISTER_STATE *registers)
Lawrence Tang794312c2022-07-05 14:46:10 +0100616{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100617 json_object *x64_registers = json_object_new_object();
618 json_object_object_add(x64_registers, "rax",
619 json_object_new_uint64(registers->Rax));
620 json_object_object_add(x64_registers, "rbx",
621 json_object_new_uint64(registers->Rbx));
622 json_object_object_add(x64_registers, "rcx",
623 json_object_new_uint64(registers->Rcx));
624 json_object_object_add(x64_registers, "rdx",
625 json_object_new_uint64(registers->Rdx));
626 json_object_object_add(x64_registers, "rsi",
627 json_object_new_uint64(registers->Rsi));
628 json_object_object_add(x64_registers, "rdi",
629 json_object_new_uint64(registers->Rdi));
630 json_object_object_add(x64_registers, "rbp",
631 json_object_new_uint64(registers->Rbp));
632 json_object_object_add(x64_registers, "rsp",
633 json_object_new_uint64(registers->Rsp));
634 json_object_object_add(x64_registers, "r8",
635 json_object_new_uint64(registers->R8));
636 json_object_object_add(x64_registers, "r9",
637 json_object_new_uint64(registers->R9));
638 json_object_object_add(x64_registers, "r10",
639 json_object_new_uint64(registers->R10));
640 json_object_object_add(x64_registers, "r11",
641 json_object_new_uint64(registers->R11));
642 json_object_object_add(x64_registers, "r12",
643 json_object_new_uint64(registers->R12));
644 json_object_object_add(x64_registers, "r13",
645 json_object_new_uint64(registers->R13));
646 json_object_object_add(x64_registers, "r14",
647 json_object_new_uint64(registers->R14));
648 json_object_object_add(x64_registers, "r15",
649 json_object_new_uint64(registers->R15));
650 json_object_object_add(x64_registers, "cs",
651 json_object_new_int(registers->Cs));
652 json_object_object_add(x64_registers, "ds",
653 json_object_new_int(registers->Ds));
654 json_object_object_add(x64_registers, "ss",
655 json_object_new_int(registers->Ss));
656 json_object_object_add(x64_registers, "es",
657 json_object_new_int(registers->Es));
658 json_object_object_add(x64_registers, "fs",
659 json_object_new_int(registers->Fs));
660 json_object_object_add(x64_registers, "gs",
661 json_object_new_int(registers->Gs));
662 json_object_object_add(x64_registers, "rflags",
663 json_object_new_uint64(registers->Rflags));
664 json_object_object_add(x64_registers, "eip",
665 json_object_new_uint64(registers->Rip));
666 json_object_object_add(x64_registers, "cr0",
667 json_object_new_uint64(registers->Cr0));
668 json_object_object_add(x64_registers, "cr1",
669 json_object_new_uint64(registers->Cr1));
670 json_object_object_add(x64_registers, "cr2",
671 json_object_new_uint64(registers->Cr2));
672 json_object_object_add(x64_registers, "cr3",
673 json_object_new_uint64(registers->Cr3));
674 json_object_object_add(x64_registers, "cr4",
675 json_object_new_uint64(registers->Cr4));
676 json_object_object_add(x64_registers, "cr8",
677 json_object_new_uint64(registers->Cr8));
678 json_object_object_add(x64_registers, "gdtr_0",
679 json_object_new_uint64(registers->Gdtr[0]));
680 json_object_object_add(x64_registers, "gdtr_1",
681 json_object_new_uint64(registers->Gdtr[1]));
682 json_object_object_add(x64_registers, "idtr_0",
683 json_object_new_uint64(registers->Idtr[0]));
684 json_object_object_add(x64_registers, "idtr_1",
685 json_object_new_uint64(registers->Idtr[1]));
686 json_object_object_add(x64_registers, "ldtr",
687 json_object_new_int(registers->Ldtr));
688 json_object_object_add(x64_registers, "tr",
689 json_object_new_int(registers->Tr));
Lawrence Tang794312c2022-07-05 14:46:10 +0100690
Lawrence Tange407b4c2022-07-21 13:54:01 +0100691 return x64_registers;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100692}
693
694//////////////////
695/// IR TO CPER ///
696//////////////////
697
698//Converts a single IA32/x64 CPER-JSON section into CPER binary, outputting to the provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100699void ir_section_ia32x64_to_cper(json_object *section, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100700{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100701 EFI_IA32_X64_PROCESSOR_ERROR_RECORD *section_cper =
702 (EFI_IA32_X64_PROCESSOR_ERROR_RECORD *)calloc(
703 1, sizeof(EFI_IA32_X64_PROCESSOR_ERROR_RECORD));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100704
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800705 uint64_t valid = 0x0;
706
707 int proc_error_info_num = json_object_get_int(json_object_object_get(
708 section, "processorErrorInfoNum")) &
709 0x3F;
710 int proc_ctx_info_num = json_object_get_int(json_object_object_get(
711 section, "processorContextInfoNum")) &
712 0x3F;
713 valid |= proc_error_info_num << 2;
714 valid |= proc_ctx_info_num << 8;
715
716 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = valid };
717 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100718
Lawrence Tange407b4c2022-07-21 13:54:01 +0100719 //Local APIC ID.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800720 if (json_object_object_get_ex(section, "localAPICID", &obj)) {
721 section_cper->ApicId = json_object_get_uint64(obj);
722 add_to_valid_bitfield(&ui64Type, 0);
723 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100724
Lawrence Tange407b4c2022-07-21 13:54:01 +0100725 //CPUID info.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800726 if (json_object_object_get_ex(section, "cpuidInfo", &obj)) {
727 json_object *cpuid_info = obj;
728 EFI_IA32_X64_CPU_ID *cpuid_info_cper =
729 (EFI_IA32_X64_CPU_ID *)section_cper->CpuIdInfo;
730 cpuid_info_cper->Eax = json_object_get_uint64(
731 json_object_object_get(cpuid_info, "eax"));
732 cpuid_info_cper->Ebx = json_object_get_uint64(
733 json_object_object_get(cpuid_info, "ebx"));
734 cpuid_info_cper->Ecx = json_object_get_uint64(
735 json_object_object_get(cpuid_info, "ecx"));
736 cpuid_info_cper->Edx = json_object_get_uint64(
737 json_object_object_get(cpuid_info, "edx"));
738 add_to_valid_bitfield(&ui64Type, 1);
739 }
740 section_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100741
Lawrence Tange407b4c2022-07-21 13:54:01 +0100742 //Flush the header to file before dealing w/ info sections.
743 fwrite(section_cper, sizeof(EFI_IA32_X64_PROCESSOR_ERROR_RECORD), 1,
744 out);
745 fflush(out);
746 free(section_cper);
747
748 //Iterate and deal with sections.
749 json_object *error_info =
750 json_object_object_get(section, "processorErrorInfo");
751 json_object *context_info =
752 json_object_object_get(section, "processorContextInfo");
John Chungf8fc7052024-05-03 20:05:29 +0800753 for (int i = 0; i < proc_error_info_num; i++) {
Lawrence Tange407b4c2022-07-21 13:54:01 +0100754 ir_ia32x64_error_info_to_cper(
755 json_object_array_get_idx(error_info, i), out);
John Chungf8fc7052024-05-03 20:05:29 +0800756 }
757 for (int i = 0; i < proc_ctx_info_num; i++) {
Lawrence Tange407b4c2022-07-21 13:54:01 +0100758 ir_ia32x64_context_info_to_cper(
759 json_object_array_get_idx(context_info, i), out);
John Chungf8fc7052024-05-03 20:05:29 +0800760 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100761}
762
763//Converts a single CPER-JSON IA32/x64 error information structure into CPER binary, outputting to the
764//provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100765void ir_ia32x64_error_info_to_cper(json_object *error_info, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100766{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100767 EFI_IA32_X64_PROCESS_ERROR_INFO *error_info_cper =
768 (EFI_IA32_X64_PROCESS_ERROR_INFO *)calloc(
769 1, sizeof(EFI_IA32_X64_PROCESS_ERROR_INFO));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100770
Lawrence Tange407b4c2022-07-21 13:54:01 +0100771 //Error structure type.
Lawrence Tang3592da72022-07-21 16:50:07 +0100772 json_object *type = json_object_object_get(error_info, "type");
773 string_to_guid(
774 &error_info_cper->ErrorType,
775 json_object_get_string(json_object_object_get(type, "guid")));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100776
Lawrence Tange407b4c2022-07-21 13:54:01 +0100777 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800778 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
779 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100780
Lawrence Tange407b4c2022-07-21 13:54:01 +0100781 //Check information, parsed based on the error type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800782 if (json_object_object_get_ex(error_info, "checkInfo", &obj)) {
783 json_object *check_info = obj;
Ed Tanous1a648562025-03-10 15:23:38 -0700784
785 int index = select_guid_from_list(
786 &error_info_cper->ErrorType, gEfiIa32x64ErrorTypeGuids,
787 sizeof(gEfiIa32x64ErrorTypeGuids) / sizeof(EFI_GUID *));
788
789 switch (index) {
790 case 0:
791 case 1:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800792 ir_ia32x64_cache_tlb_check_error_to_cper(
793 check_info,
794 (EFI_IA32_X64_CACHE_CHECK_INFO
795 *)&error_info_cper->CheckInfo);
Ed Tanous1a648562025-03-10 15:23:38 -0700796 break;
797 case 2:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800798 ir_ia32x64_bus_check_error_to_cper(
799 check_info,
800 (EFI_IA32_X64_BUS_CHECK_INFO *)&error_info_cper
801 ->CheckInfo);
Ed Tanous1a648562025-03-10 15:23:38 -0700802 break;
803 case 3:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800804 ir_ia32x64_ms_check_error_to_cper(
805 check_info,
806 (EFI_IA32_X64_MS_CHECK_INFO *)&error_info_cper
807 ->CheckInfo);
Ed Tanous1a648562025-03-10 15:23:38 -0700808 break;
809 default:
810 //Unknown check information.
Ed Tanous50b966f2025-03-11 09:06:19 -0700811 cper_print_log(
812 "WARN: Invalid/unknown check information GUID found in IA32/x64 CPER section. Ignoring.\n");
Ed Tanous1a648562025-03-10 15:23:38 -0700813 break;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800814 }
815 add_to_valid_bitfield(&ui64Type, 0);
John Chungf8fc7052024-05-03 20:05:29 +0800816 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100817
Lawrence Tange407b4c2022-07-21 13:54:01 +0100818 //Miscellaneous numeric fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800819 if (json_object_object_get_ex(error_info, "targetAddressID", &obj)) {
820 error_info_cper->TargetId = json_object_get_uint64(obj);
821 add_to_valid_bitfield(&ui64Type, 1);
822 }
823 if (json_object_object_get_ex(error_info, "requestorID", &obj)) {
824 error_info_cper->RequestorId = json_object_get_uint64(obj);
825 add_to_valid_bitfield(&ui64Type, 2);
826 }
827 if (json_object_object_get_ex(error_info, "responderID", &obj)) {
828 error_info_cper->ResponderId = json_object_get_uint64(obj);
829 add_to_valid_bitfield(&ui64Type, 3);
830 }
831 if (json_object_object_get_ex(error_info, "instructionPointer", &obj)) {
832 error_info_cper->InstructionIP = json_object_get_uint64(obj);
833 add_to_valid_bitfield(&ui64Type, 4);
834 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100835
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800836 error_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tange407b4c2022-07-21 13:54:01 +0100837 //Write out to stream, then free resources.
838 fwrite(error_info_cper, sizeof(EFI_IA32_X64_PROCESS_ERROR_INFO), 1,
839 out);
840 fflush(out);
841 free(error_info_cper);
Lawrence Tangd0c88842022-07-13 14:51:17 +0100842}
843
844//Converts a single CPER-JSON IA32/x64 cache/TLB check error info structure to CPER binary.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100845void ir_ia32x64_cache_tlb_check_error_to_cper(
846 json_object *check_info, EFI_IA32_X64_CACHE_CHECK_INFO *check_info_cper)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100847{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100848 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800849 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
850 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100851
Lawrence Tange407b4c2022-07-21 13:54:01 +0100852 //Transaction type, operation.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800853 if (json_object_object_get_ex(check_info, "transactionType", &obj)) {
854 check_info_cper->TransactionType =
855 readable_pair_to_integer(obj);
856 add_to_valid_bitfield(&ui64Type, 0);
857 }
858 if (json_object_object_get_ex(check_info, "operation", &obj)) {
859 check_info_cper->Operation = readable_pair_to_integer(obj);
860 add_to_valid_bitfield(&ui64Type, 1);
861 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100862
Lawrence Tange407b4c2022-07-21 13:54:01 +0100863 //Miscellaneous raw value fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800864 if (json_object_object_get_ex(check_info, "level", &obj)) {
865 check_info_cper->Level = json_object_get_uint64(obj);
866 add_to_valid_bitfield(&ui64Type, 2);
867 }
868 if (json_object_object_get_ex(check_info, "processorContextCorrupt",
869 &obj)) {
870 check_info_cper->ContextCorrupt = json_object_get_boolean(obj);
871 add_to_valid_bitfield(&ui64Type, 3);
872 }
873 if (json_object_object_get_ex(check_info, "uncorrected", &obj)) {
874 check_info_cper->ErrorUncorrected =
875 json_object_get_boolean(obj);
876 add_to_valid_bitfield(&ui64Type, 4);
877 }
878 if (json_object_object_get_ex(check_info, "preciseIP", &obj)) {
879 check_info_cper->PreciseIp = json_object_get_boolean(obj);
880 add_to_valid_bitfield(&ui64Type, 5);
881 }
882 if (json_object_object_get_ex(check_info, "restartableIP", &obj)) {
883 check_info_cper->RestartableIp = json_object_get_boolean(obj);
884 add_to_valid_bitfield(&ui64Type, 6);
885 }
886 if (json_object_object_get_ex(check_info, "overflow", &obj)) {
887 check_info_cper->Overflow = json_object_get_boolean(obj);
888 add_to_valid_bitfield(&ui64Type, 7);
889 }
890 check_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100891}
892
893//Converts a single CPER-JSON IA32/x64 bus error info structure to CPER binary.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100894void ir_ia32x64_bus_check_error_to_cper(
895 json_object *check_info, EFI_IA32_X64_BUS_CHECK_INFO *check_info_cper)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100896{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100897 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800898 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
899 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100900
Lawrence Tange407b4c2022-07-21 13:54:01 +0100901 //Readable pair fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800902 if (json_object_object_get_ex(check_info, "transactionType", &obj)) {
903 check_info_cper->TransactionType =
904 readable_pair_to_integer(obj);
905 add_to_valid_bitfield(&ui64Type, 0);
906 }
907 if (json_object_object_get_ex(check_info, "operation", &obj)) {
908 check_info_cper->Operation = readable_pair_to_integer(obj);
909 add_to_valid_bitfield(&ui64Type, 1);
910 }
911 if (json_object_object_get_ex(check_info, "participationType", &obj)) {
912 check_info_cper->ParticipationType =
913 readable_pair_to_integer(obj);
914 add_to_valid_bitfield(&ui64Type, 8);
915 }
916
917 if (json_object_object_get_ex(check_info, "addressSpace", &obj)) {
918 check_info_cper->AddressSpace = readable_pair_to_integer(obj);
919 add_to_valid_bitfield(&ui64Type, 10);
920 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100921
Lawrence Tange407b4c2022-07-21 13:54:01 +0100922 //Miscellaneous raw value fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800923 if (json_object_object_get_ex(check_info, "level", &obj)) {
924 check_info_cper->Level = json_object_get_uint64(obj);
925 add_to_valid_bitfield(&ui64Type, 2);
926 }
927 if (json_object_object_get_ex(check_info, "processorContextCorrupt",
928 &obj)) {
929 check_info_cper->ContextCorrupt = json_object_get_boolean(obj);
930 add_to_valid_bitfield(&ui64Type, 3);
931 }
932 if (json_object_object_get_ex(check_info, "uncorrected", &obj)) {
933 check_info_cper->ErrorUncorrected =
934 json_object_get_boolean(obj);
935 add_to_valid_bitfield(&ui64Type, 4);
936 }
937 if (json_object_object_get_ex(check_info, "preciseIP", &obj)) {
938 check_info_cper->PreciseIp = json_object_get_boolean(obj);
939 add_to_valid_bitfield(&ui64Type, 5);
940 }
941 if (json_object_object_get_ex(check_info, "restartableIP", &obj)) {
942 check_info_cper->RestartableIp = json_object_get_boolean(obj);
943 add_to_valid_bitfield(&ui64Type, 6);
944 }
945 if (json_object_object_get_ex(check_info, "overflow", &obj)) {
946 check_info_cper->Overflow = json_object_get_boolean(obj);
947 add_to_valid_bitfield(&ui64Type, 7);
948 }
949 if (json_object_object_get_ex(check_info, "timedOut", &obj)) {
950 check_info_cper->TimeOut = json_object_get_boolean(obj);
951 add_to_valid_bitfield(&ui64Type, 9);
952 }
953 check_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100954}
955
956//Converts a single CPER-JSON IA32/x64 MS error info structure to CPER binary.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100957void ir_ia32x64_ms_check_error_to_cper(
958 json_object *check_info, EFI_IA32_X64_MS_CHECK_INFO *check_info_cper)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100959{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100960 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800961 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
962 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100963
Lawrence Tange407b4c2022-07-21 13:54:01 +0100964 //Type of MS check error.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800965 if (json_object_object_get_ex(check_info, "errorType", &obj)) {
966 check_info_cper->ErrorType = readable_pair_to_integer(obj);
967 add_to_valid_bitfield(&ui64Type, 0);
968 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100969
Lawrence Tange407b4c2022-07-21 13:54:01 +0100970 //Miscellaneous raw value fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800971 if (json_object_object_get_ex(check_info, "processorContextCorrupt",
972 &obj)) {
973 check_info_cper->ContextCorrupt = json_object_get_boolean(obj);
974 add_to_valid_bitfield(&ui64Type, 1);
975 }
976 if (json_object_object_get_ex(check_info, "uncorrected", &obj)) {
977 check_info_cper->ErrorUncorrected =
978 json_object_get_boolean(obj);
979 add_to_valid_bitfield(&ui64Type, 2);
980 }
981 if (json_object_object_get_ex(check_info, "preciseIP", &obj)) {
982 check_info_cper->PreciseIp = json_object_get_boolean(obj);
983 add_to_valid_bitfield(&ui64Type, 3);
984 }
985 if (json_object_object_get_ex(check_info, "restartableIP", &obj)) {
986 check_info_cper->RestartableIp = json_object_get_boolean(obj);
987 add_to_valid_bitfield(&ui64Type, 4);
988 }
989 if (json_object_object_get_ex(check_info, "overflow", &obj)) {
990 check_info_cper->Overflow = json_object_get_boolean(obj);
991 add_to_valid_bitfield(&ui64Type, 5);
992 }
993 check_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100994}
995
996//Converts a single CPER-JSON IA32/x64 context information structure into CPER binary, outputting to the
997//provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100998void ir_ia32x64_context_info_to_cper(json_object *context_info, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100999{
Lawrence Tange407b4c2022-07-21 13:54:01 +01001000 EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *context_info_cper =
1001 (EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *)calloc(
1002 1, sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO));
Lawrence Tangd0c88842022-07-13 14:51:17 +01001003
Lawrence Tange407b4c2022-07-21 13:54:01 +01001004 //Register context type.
1005 context_info_cper->RegisterType = (UINT16)readable_pair_to_integer(
1006 json_object_object_get(context_info, "registerContextType"));
Lawrence Tangd0c88842022-07-13 14:51:17 +01001007
Lawrence Tange407b4c2022-07-21 13:54:01 +01001008 //Miscellaneous numeric fields.
1009 context_info_cper->ArraySize = (UINT16)json_object_get_uint64(
1010 json_object_object_get(context_info, "registerArraySize"));
1011 context_info_cper->MsrAddress = (UINT32)json_object_get_uint64(
1012 json_object_object_get(context_info, "msrAddress"));
1013 context_info_cper->MmRegisterAddress = json_object_get_uint64(
1014 json_object_object_get(context_info, "mmRegisterAddress"));
Lawrence Tangd0c88842022-07-13 14:51:17 +01001015
Lawrence Tange407b4c2022-07-21 13:54:01 +01001016 //Flush header to stream.
1017 fwrite(context_info_cper, sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO),
1018 1, out);
1019 fflush(out);
Lawrence Tangd0c88842022-07-13 14:51:17 +01001020
Lawrence Tange407b4c2022-07-21 13:54:01 +01001021 //Handle the register array, depending on type provided.
1022 json_object *register_array =
1023 json_object_object_get(context_info, "registerArray");
1024 if (context_info_cper->RegisterType == EFI_REG_CONTEXT_TYPE_IA32) {
1025 ir_ia32x64_ia32_registers_to_cper(register_array, out);
1026 } else if (context_info_cper->RegisterType ==
1027 EFI_REG_CONTEXT_TYPE_X64) {
1028 ir_ia32x64_x64_registers_to_cper(register_array, out);
1029 } else {
1030 //Unknown/structure is not defined.
1031 json_object *encoded =
1032 json_object_object_get(register_array, "data");
Ed Tanousa7d2cdd2024-07-15 11:07:27 -07001033 int32_t decoded_len = 0;
1034 const char *j_string = json_object_get_string(encoded);
1035 int j_size = json_object_get_string_len(encoded);
1036 UINT8 *decoded = base64_decode(j_string, j_size, &decoded_len);
1037 if (decoded == NULL) {
Ed Tanous50b966f2025-03-11 09:06:19 -07001038 cper_print_log(
1039 "Failed to allocate decode output buffer. \n");
John Chungf8fc7052024-05-03 20:05:29 +08001040 } else {
John Chungf8fc7052024-05-03 20:05:29 +08001041 fwrite(decoded, decoded_len, 1, out);
1042 fflush(out);
1043 free(decoded);
1044 }
Lawrence Tange407b4c2022-07-21 13:54:01 +01001045 }
Lawrence Tangd0c88842022-07-13 14:51:17 +01001046
Lawrence Tange407b4c2022-07-21 13:54:01 +01001047 //Free remaining resources.
1048 free(context_info_cper);
Lawrence Tangd0c88842022-07-13 14:51:17 +01001049}
1050
1051//Converts a single CPER-JSON IA32 register array into CPER binary, outputting to the given stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +01001052void ir_ia32x64_ia32_registers_to_cper(json_object *registers, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +01001053{
Lawrence Tange407b4c2022-07-21 13:54:01 +01001054 EFI_CONTEXT_IA32_REGISTER_STATE register_state;
1055 register_state.Eax = (UINT32)json_object_get_uint64(
1056 json_object_object_get(registers, "eax"));
1057 register_state.Ebx = (UINT32)json_object_get_uint64(
1058 json_object_object_get(registers, "ebx"));
1059 register_state.Ecx = (UINT32)json_object_get_uint64(
1060 json_object_object_get(registers, "ecx"));
1061 register_state.Edx = (UINT32)json_object_get_uint64(
1062 json_object_object_get(registers, "edx"));
1063 register_state.Esi = (UINT32)json_object_get_uint64(
1064 json_object_object_get(registers, "esi"));
1065 register_state.Edi = (UINT32)json_object_get_uint64(
1066 json_object_object_get(registers, "edi"));
1067 register_state.Ebp = (UINT32)json_object_get_uint64(
1068 json_object_object_get(registers, "ebp"));
1069 register_state.Esp = (UINT32)json_object_get_uint64(
1070 json_object_object_get(registers, "esp"));
1071 register_state.Cs = (UINT16)json_object_get_uint64(
1072 json_object_object_get(registers, "cs"));
1073 register_state.Ds = (UINT32)json_object_get_uint64(
1074 json_object_object_get(registers, "ds"));
1075 register_state.Ss = (UINT16)json_object_get_uint64(
1076 json_object_object_get(registers, "ss"));
1077 register_state.Es = (UINT16)json_object_get_uint64(
1078 json_object_object_get(registers, "es"));
1079 register_state.Fs = (UINT16)json_object_get_uint64(
1080 json_object_object_get(registers, "fs"));
1081 register_state.Gs = (UINT16)json_object_get_uint64(
1082 json_object_object_get(registers, "gs"));
1083 register_state.Eflags = (UINT32)json_object_get_uint64(
1084 json_object_object_get(registers, "eflags"));
1085 register_state.Eip = (UINT32)json_object_get_uint64(
1086 json_object_object_get(registers, "eip"));
1087 register_state.Cr0 = (UINT32)json_object_get_uint64(
1088 json_object_object_get(registers, "cr0"));
1089 register_state.Cr1 = (UINT32)json_object_get_uint64(
1090 json_object_object_get(registers, "cr1"));
1091 register_state.Cr2 = (UINT32)json_object_get_uint64(
1092 json_object_object_get(registers, "cr2"));
1093 register_state.Cr3 = (UINT32)json_object_get_uint64(
1094 json_object_object_get(registers, "cr3"));
1095 register_state.Cr4 = (UINT32)json_object_get_uint64(
1096 json_object_object_get(registers, "cr4"));
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001097
Lawrence Tange407b4c2022-07-21 13:54:01 +01001098 //64-bit registers are split into two 32-bit parts.
1099 UINT64 gdtr = json_object_get_uint64(
1100 json_object_object_get(registers, "gdtr"));
1101 register_state.Gdtr[0] = gdtr & 0xFFFFFFFF;
1102 register_state.Gdtr[1] = gdtr >> 32;
1103 UINT64 idtr = json_object_get_uint64(
1104 json_object_object_get(registers, "idtr"));
1105 register_state.Idtr[0] = idtr & 0xFFFFFFFF;
1106 register_state.Idtr[1] = idtr >> 32;
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001107
Lawrence Tange407b4c2022-07-21 13:54:01 +01001108 //16-bit registers.
1109 register_state.Ldtr = (UINT16)json_object_get_uint64(
1110 json_object_object_get(registers, "ldtr"));
1111 register_state.Tr = (UINT16)json_object_get_uint64(
1112 json_object_object_get(registers, "tr"));
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001113
Lawrence Tange407b4c2022-07-21 13:54:01 +01001114 //Write out to stream.
1115 fwrite(&register_state, sizeof(EFI_CONTEXT_IA32_REGISTER_STATE), 1,
1116 out);
1117 fflush(out);
Lawrence Tangd0c88842022-07-13 14:51:17 +01001118}
1119
1120//Converts a single CPER-JSON x64 register array into CPER binary, outputting to the given stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +01001121void ir_ia32x64_x64_registers_to_cper(json_object *registers, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +01001122{
Lawrence Tange407b4c2022-07-21 13:54:01 +01001123 EFI_CONTEXT_X64_REGISTER_STATE register_state;
1124 register_state.Rax = json_object_get_uint64(
1125 json_object_object_get(registers, "rax"));
1126 register_state.Rbx = json_object_get_uint64(
1127 json_object_object_get(registers, "rbx"));
1128 register_state.Rcx = json_object_get_uint64(
1129 json_object_object_get(registers, "rcx"));
1130 register_state.Rdx = json_object_get_uint64(
1131 json_object_object_get(registers, "rdx"));
1132 register_state.Rsi = json_object_get_uint64(
1133 json_object_object_get(registers, "rsi"));
1134 register_state.Rdi = json_object_get_uint64(
1135 json_object_object_get(registers, "rdi"));
1136 register_state.Rbp = json_object_get_uint64(
1137 json_object_object_get(registers, "rbp"));
1138 register_state.Rsp = json_object_get_uint64(
1139 json_object_object_get(registers, "rsp"));
1140 register_state.R8 =
1141 json_object_get_uint64(json_object_object_get(registers, "r8"));
1142 register_state.R9 =
1143 json_object_get_uint64(json_object_object_get(registers, "r9"));
1144 register_state.R10 = json_object_get_uint64(
1145 json_object_object_get(registers, "r10"));
1146 register_state.R11 = json_object_get_uint64(
1147 json_object_object_get(registers, "r11"));
1148 register_state.R12 = json_object_get_uint64(
1149 json_object_object_get(registers, "r12"));
1150 register_state.R13 = json_object_get_uint64(
1151 json_object_object_get(registers, "r13"));
1152 register_state.R14 = json_object_get_uint64(
1153 json_object_object_get(registers, "r14"));
1154 register_state.R15 = json_object_get_uint64(
1155 json_object_object_get(registers, "r15"));
1156 register_state.Cs = (UINT16)json_object_get_int(
1157 json_object_object_get(registers, "cs"));
1158 register_state.Ds = (UINT16)json_object_get_int(
1159 json_object_object_get(registers, "ds"));
1160 register_state.Ss = (UINT16)json_object_get_int(
1161 json_object_object_get(registers, "ss"));
1162 register_state.Es = (UINT16)json_object_get_int(
1163 json_object_object_get(registers, "es"));
1164 register_state.Fs = (UINT16)json_object_get_int(
1165 json_object_object_get(registers, "fs"));
1166 register_state.Gs = (UINT16)json_object_get_int(
1167 json_object_object_get(registers, "gs"));
1168 register_state.Resv1 = 0;
1169 register_state.Rflags = json_object_get_uint64(
1170 json_object_object_get(registers, "rflags"));
1171 register_state.Rip = json_object_get_uint64(
1172 json_object_object_get(registers, "eip"));
1173 register_state.Cr0 = json_object_get_uint64(
1174 json_object_object_get(registers, "cr0"));
1175 register_state.Cr1 = json_object_get_uint64(
1176 json_object_object_get(registers, "cr1"));
1177 register_state.Cr2 = json_object_get_uint64(
1178 json_object_object_get(registers, "cr2"));
1179 register_state.Cr3 = json_object_get_uint64(
1180 json_object_object_get(registers, "cr3"));
1181 register_state.Cr4 = json_object_get_uint64(
1182 json_object_object_get(registers, "cr4"));
1183 register_state.Cr8 = json_object_get_uint64(
1184 json_object_object_get(registers, "cr8"));
1185 register_state.Gdtr[0] = json_object_get_uint64(
1186 json_object_object_get(registers, "gdtr_0"));
1187 register_state.Gdtr[1] = json_object_get_uint64(
1188 json_object_object_get(registers, "gdtr_1"));
1189 register_state.Idtr[0] = json_object_get_uint64(
1190 json_object_object_get(registers, "idtr_0"));
1191 register_state.Idtr[1] = json_object_get_uint64(
1192 json_object_object_get(registers, "idtr_1"));
1193 register_state.Ldtr = (UINT16)json_object_get_int(
1194 json_object_object_get(registers, "ldtr"));
1195 register_state.Tr = (UINT16)json_object_get_int(
1196 json_object_object_get(registers, "tr"));
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001197
Lawrence Tange407b4c2022-07-21 13:54:01 +01001198 //Write out to stream.
1199 fwrite(&register_state, sizeof(EFI_CONTEXT_X64_REGISTER_STATE), 1, out);
1200 fflush(out);
John Chungf8fc7052024-05-03 20:05:29 +08001201}